持续更新中。。。 有道笔记链接:http://note.youdao.com/noteshare?id=10a0a86a3499f92cf26371f2698b97d2
Git网上平台
码云 http://git.oschina.net/ 开源中国( https://www.oschina.net/)旗下的Git代码仓库
GitHub https://github.com/
CSDN代码托管平台(Git) https://code.csdn.net
Bitbucket https://bitbucket.org/
内网自己搭建:
开源平台:Gogs https://gogs.io/ 国内人开发的,可以在windows/linux多个平台上安装,简单易行
Git客户端
可以在这个平台找到各个系统的各种客户端
windows平台:
Git Extensions http://gitextensions.github.io/
安装时会带有git bash,记得在安装时勾选右键显示git GUI here和git bash here选项,可以选择使用GUI,也可以使用bash,比较方便
GitKraken: 官方网站:https://www.gitkraken.com/
SourceTree
Github Desktop
Pycharm/VCS/Git:
Pycharm自带的git管理插件,也很好用,带有可视化的log和history,版本比较等等。
linux平台:
Git:
# sudo apt-get install git
GitKraken: 官方网站:https://www.gitkraken.com/
GitKraken 是一个跨平台的,优雅和高效用于 Linux 的 Git 客户端。它适用于类 Unix 系统,例如 Linux 和 Mac OS X,以及 Windows。它旨在通过以下功能来提高 Git 用户的工作效率:
视觉交互和提示
100% 单机
支持多个配置文件
支持单点击撤销和重做功能
内置的合并工具
快速和直观的搜索工具
很容易适应用户的工作空间,同时支持子模块和 Gitflow
与用户的 GitHub 的或 Bitbucket 帐户集成
键盘快捷键以及其它更多。
Pycharm/VCS/Git:
Pycharm自带的git管理插件,也很好用,带有可视化的log和history,版本比较等等。
Mac平台:
Xcode自带git,Xcode本身需要额外安装
GitKraken: 官方网站:https://www.gitkraken.com/
SourceTree
Github Desktop
Pycharm/VCS/Git:
Pycharm自带的git管理插件,也很好用,带有可视化的log和history,版本比较等等。
Git教程
Git和CVS
记得之前收集过一些资料,回家看看电脑上有没有
如果你不熟悉Git,点此查看权威Git书籍 ProGit(中文版),新手老鸟均适合。http://git.oschina.net/progit/
git官网:http://git-scm.com
git客户端下载地址:
git手册:http://git-scm.com/docs
网友整理的Git@osc教程 https://gitee.com/oschina/git-osc/wikis/%E5%B8%AE%E5%8A%A9#%E7%BB%A7%E7%BB%AD%E9%98%85%E8%AF%BB
git push & git pull 推送/拉取分支 http://blog.csdn.net/litianze99/article/details/52452521
- git config --global user.name “用户名”
- git config --global user.email “邮箱”
- 执行生成公钥和私钥的命令:ssh-keygen -t rsa 并按回车3下
- 执行查看公钥的命令:cat ~/.ssh/id_rsa.pub
初始化一个Git仓库,使用git init命令。
添加文件到Git仓库,分两步:
- 第一步,使用命令git add <file>将工作区的文件添加到暂存区,注意,可反复多次使用,添加多个文件;
- 第二步,使用命令git commit将暂存区的文件提交到当前分支,完成。
- git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。每次修改,如果不add到暂存区,那就不会加入到commit中。
要随时掌握工作区的状态,使用git status命令:
- 如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
版本退回:
- HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
- 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
- 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
管理和撤销修改:
- 场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令git checkout -- file(回到上一次git add的状态(用暂存区中的文件替换工作区中的文件),如果没有git add,就回到上一次git commit的状态(用版本库当前分支中的文件替换工作区中的文件))。
- 场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到了场景1,第二步按场景1操作。
- 场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考版本回退一节,不过前提是没有推送到远程库。
删除文件:
- 命令git rm用于从版本库中删除一个文件(将文件从工作区删除,并添加改动到暂存区,还需要使用git commit命令将删除操作提交到当前分支)(注意,用rm命令是从我们的机器上删除文件,但是这个删除操作git版本库会记录下来,如果我们确实不想要它了,就需要在版本库中也删除这个文件)。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。
远程仓库:
- 要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;关联后,使用命令git push -u origin master第一次推送master分支的所有内容到远程仓库,并与远程仓库的master分支关联(如无master分支则新建并关联);此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
- git push <远程主机名> <本地分支名>:<远程分支名>
- git push origin :master 等同于 $ git push origin --delete master
- git pull <远程主机名> <远程分支名>:<本地分支名>
- git pull origin master 如果省略本地分支,则将自动合并到当前所在分支上
- 要克隆一个仓库,首先必须知道仓库的地址,然后使用git clone命令克隆。Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。
Git鼓励大量使用分支:
- 查看分支:git branch
- 创建分支:git branch <name>
- 切换分支:git checkout <name>
- 创建+切换分支:git checkout -b <name>
- 合并某分支到当前分支:git merge [--no-ff] <name>
- 删除分支:git branch -d <name>
解决冲突:
- 当Git无法自动合并分支时,就必须首先解决冲突(如果有冲突,在git merge时会提示冲突的文件,git status也可以告诉我们冲突的文件)(打开有冲突的文件,Git会用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们要修改这些内容,把标记符都去掉,改成我们想要的,然后保存)。解决冲突后,再提交(git add & git commit),合并完成。
- 用git log --graph命令可以看到分支合并图。($ git log --graph --pretty=oneline --abbrev-commit)
分支管理策略:
- 合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。
- 在实际开发中,我们应该按照几个基本原则进行分支管理:
- 首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
- 那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
- 你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
- 所以,团队合作的分支看起来就像这样:
Bug分支:
- 当有Bug需要修复,而我们的dev分支的工作区还有没做完的工作,这个时候先用git stash存储当前工作区,这个时候工作区就被清空了(可以多次stash,系统会保存成stash list)
- 然后git checkout到你想要的分支上(一般是在master分支上修复bug),创建bug修复分支:git checkout -b issue-101,修复bug,提交修改到这个分支,修复完成后,切换到master分支,并完成合并,最后删除issue-101分支
- 恢复dev分支的工作区:切换到dev分支上,用git stash list命令查看保存的工作区列表,然后选择要恢复的工作区(eg. stash@{0})恢复:一是用git stash apply stash@{0}恢复,但是恢复后,stash内容并不删除,你需要用git stash drop stash@{0}来删除;另一种方式是用git stash pop stash@{0},恢复的同时把stash内容也删了。如果stash list中只有一个stash,可以不加stash@{0}。
- 接下来就可以继续我们之前的工作了,工作完成后将工作区提交到dev分支即可。
Feature分支:
- 开发一个新feature,最好新建一个分支feature-name;
- 如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。
多人协作时,哪些分支需要推送,哪些不需要呢?更多参考我们自己制定的“分支管理策略”
- master分支是主分支,因此要时刻与远程同步;
- dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;
- bug分支只用于在本地修复bug,就没必要推到远程了,修复完成后合并到master上,然后同步master即可。除非老板要看看你每周到底修复了几个bug;
- feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
多人协作的工作模式通常是这样:
- 首先,可以试图用git push origin branch-name推送自己的修改;
- 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
- 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!
- 如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to=origin/branch-name branch-name。
- 如果git pull提示“fatal: refusing to merge unrelated histories”,这是因为这两个项目没有共同的祖先,没法合并。在进行git pull 时,添加一个可选项: git pull origin master --allow-unrelated-histories,如果还不行,就参考这篇文章:http://blog.csdn.net/zhangmingbao2016/article/details/73478899 。最根本的解决方法是重新从远程仓库中clone下来一个分支,重新开始。
未完待续。。。。。。。
忽略特殊文件:
- 忽略某些文件时,需要编写.gitignore;不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。所有配置文件可以直接在线浏览:https://github.com/github/gitignore
- .gitignore文件本身要放到版本库(项目所在的文件夹,和.git文件夹在同一级)里,并且可以对.gitignore做版本管理!
- 对于python项目,使用github为我们提供的python.gitignore就可以了,但是如果你用pycharm开发程序,还需要在.gitignore中添加忽略项:.idea/,这是pycharm的工作目录,否则会影响合并.
分支管理策略
#分支管理策略v1.0
## master
属性:Project Branch
主分支,稳定版,由管理员负责运维。
## dev
属性:Project Branch
开发分支,项目组长负责运维,所有的新开发的东西都往这个分支合并。如果测试稳定,合并到master。
## feature-name
属性:Normal Branch
正在开发的功能,开发完成后,提交到远程仓库,通知项目组长,由项目组长检查后合并到dev分支
- 如果是一个人开发,就不需要一定要同步到gitee.com,除非是为了备份;
- 如果是多人协同开发,需要在远程仓库上同步一份,然后每个人新建feature-name-yourname个人开发分支。
- 要尽量避免多人开发一个功能,要把功能尽可能细化到一个人的工作量(原子性)。
## bug-no
属性:Normal Branch
需要修复的bug,修复完成后,提交到远程仓库,通知项目组长,由项目组长检查后同步到master。
尽量避免多人修复同一bug。
任务分配策略
多人协作的基础在于任务分配,好的任务分配可以事半功倍,降低协作的复杂性。
一个项目首先要根据复杂程度划分阶段,由易入难,由简入繁,首先实现核心功能,然后才是增值功能;每个阶段开发完成后,合并到master,标记为vi.0
对于每一个阶段,制定架构,划分模块,各个模块之间必须要制定清晰的API,而且要考虑以后的升级,架构尽可能做的全面一点、兼容性高一点;
对于每一个模块,制定架构,拆分功能函数,每个函数确定好功能、参数类型、返回值类型,交给个人开发。
Project: (branch:master)
step1: (branch:dev----merge--->master "v1.0")
module1---->团队1: (branch:feature-module1----merge--->dev "module1")
func1---->个人1 (branch:feature-module1-func1----merge--->feature-module1 "func1")
func2---->个人2 (branch:feature-module1-func2----merge--->feature-module1 "func2")
funcn---->个人n (branch:feature-module1-funcn----merge--->feature-module1 "funcn")
module2---->团队2: ...... (branch:feature-module2----merge--->dev "module2")
modulen---->团队n: ...... (branch:feature-modulen----merge--->dev "modulen")
step2: ...... (branch: dev----merge--->master "v2.0")
stepn: ...... (branch: dev----merge--->master "vn.0")
在任务执行过程中,中途反复沟通的成本还是很高的,因此分工最好是原子的,即每一份工作做好能够一个人完成,尽量减少内容的交叉。当然完全不交叉的分工几乎不可能,这就需要看架构师的功力和项目经理的管理能力了。我个人认为好的架构师也应该是一个好的项目经理。
高效而短促的会议,在会议之后一定要现场做出书面结论。