Labels

Friday, March 4, 2016

GitHub 使用指南 Part II


GitHub 使用指南 Part II
Udacity Git课程学习笔记

合并远程改变(Merging remote change

Scenario 1:仅本地改变

如果GitHub上的repository克隆到本地,本地修改了目录中的文件,commit后通过git status查看,当前分支领先origin/master,此时可以通过git push origin来发布本地提交,使远程(GitHub)与本地同步

Scenario 2:仅远程改变

使用git pull origin master,远程master branch便同步到本地

Scenario 3:本地远程都改变(本地工作在master分支)

这是多人在GitHub上共同协作一个project时经常发生的情况。遇到这种情况时,我们可以先使用git fetch origin把远程master branch添加到本地成为origin/master而不影响本地master branch,之后我们可以通过git diff origin/master master来比较这两个branch的不同,再使用git merge master origin/master来合并这两个branch。或者我们可以直接使用git pull origin master,这条命令就等价于git fetch origingit merge master origin/master
  1. terminal中输入git pull origin master,如果我们不知道其他协作者都做出了什么改变,那么分别使用git fetchgit merge能使我们在merge前有检查别人改变的机会
  2. Git提示我们自动合并失败,检测到合并冲突并告诉我们有哪些冲突文件,此时我们在在merging过程中
  3. 使用文本编辑器解决冲突代码段,再使用git add conflict_file将修改后的文件存于staging area
  4. 使用git commit结束merging过程,我们可以再使用git pull origin master验证是否完成合并,这时git提示我们以及up to date,证明我们合并成功
  5. 最后用git push origin master来发布我们的本地提交
注意:git loggit status都是本地执行的命令。如果我们使用git log origin/master,查看到的不是位于GitHubmaster branch的最新commit记录,而是从上次git pull origin master以来就保存在本地的master branch。如果在git pull后我们又完成了一次commit,那么git status会告诉我们当前分支master领先于origin/master

Scenario 4:本地远程都改变(本地工作在exp分支)

本地工作在exp分支,协作者工作在master分支并使用pull request更新了GitHub上的master分支。这时,由于自己的origin/master已经out of date了,若现在自己提交pull requestGitHub以及无法自动合并了,同意pull request按钮便灰。这时需要我们手动解决冲突才能让GitHub上的同意pull request按钮便绿。
  1. 先切换到master分支
  2. terminal中输入git pull origin master,如果我们不知道其他协作者都做出了什么改变,那么分别使用git fetchgit merge能使我们在merge前有检查别人改变的机会
  3. master分支成功更新,此时再切换回exp分支
  4. 使用git merge master expGit提示我们自动合并失败,检测到合并冲突并告诉我们有哪些冲突文件,此时我们在在merging过程中
  5. 使用文本编辑器解决冲突代码段,再使用git add conflict_file将修改后的文件存于staging area
  6. 使用git commit结束merging过程
  7. 最后用git push origin exp来发布我们的本地提交
  8. 等待协作者点击同意pull request
  9. 使用git pull来更新本地repository
注意:自动合并的指的是fast-forward merges,合并条件在下小节。
scenario 3scenario 4我们可以看出,本地工作在master分支时,我们只需要简单的pullpush来更新本地master分支和提交本地改变。如果本地没有工作在master分支时,事情就要复杂的多,我们首先要使用pull来更新本地master分支,在把本地master分支merge到本地exp分支,然后才能push exp分支。那么在本地使用非master分支有什么好处呢?
实际上,在贡献公共repository时,我们一般都会在自己fork下的非master分支工作,这样做我们能使本地master分支实时与原master分支更新,直到我们工作完毕时,再将本地master分支merge到我们工作的非master分支中并提交pull request

Fast-forwar merges

Git pull等价于git fetchgit merge,但有时候git pull不会像git fetchgit merge产生merge commit,这时为什么呢?是因为产生了fast-forward merges,如果我们merge两个commits,假设是ab,其中a正好是bancestor,那么就会发生fast-forward merge,因为a包含b的全部历史commit信息。
注意:我们说abancestor意思是从版本a出发回溯到版本b

总结






Local working directory Local staging area Local master branch GitHub master branch
Edit and save README.md ×





Git add README.md

×



Git commit



×

Git pull origin master × × ×

Git push origin master





×
Merge alt pull request





×



Pull Request:多人协作时请求merge

如果有许多协作者在GitHub上同一个repository上合作写代码,自己有新想法想要实施有不想影响master branch时该怎么办呢?
  1. 使用git branch exp_branch建立exp_branch分支,再用git checkout exp_branch使exp_branch成为当前默认分支
  2. exp_branch上实施想法后用git commit提交该分支
  3. 使用git push origin exp_branchGitHub上更新出一个新的分支
  4. GitHub上创建一个pull request,如果GitHub上的repository是从别人那里fork来的,默认base是别人的master分支。如果是在自己的GitHub上进行的多人协作project,记得要将base改为自己的master分支。
  5. 如果有协作者发现自己的pull request中有错误,这时后我们可以在本地更改后继续git push origin exp_branch来更新自己的pull request
注意:多人协作时,不要使用git push来更新remote masterpull request应该是交流changes时唯一使用的工具,否则大家都使用git push的话,有些人还没注意到呢,remote master分支就已经改变了,这是非常不好的

添加Original repository为本地cloneremote

GitHub上参与public repository时经常发生的一个问题是,自己GitHub上的Fork已经过时了,而自己在Fork的本地克隆上的非master分支上已经做出了更改,这时pull request会与其他协作者的pull request发生冲突,这时候改怎么办呢?
注意:这里我们说的非master分支就是上面的exp_branch或是途中的 stop-drop-roll分支,也就是我们在本地当前工作的分支
GitHub Local
Original Fork Clone






  1. 首先将Originalrepository设置为remoteupstream
git remote add upstream http_url
  1. 更新本地clonemaster分支与Originalmaster分支一致
git checkout master
git pull upstream master
  1. 把本地master分支merge进自己工作的分支
git checkout exp_branch
git merge master exp_branch
  1. 解决冲突后把本地master分支和工作分支push到自己GitHub上的Fork
打开文本编辑工具,根据提示修改冲突
git add conflict_file #把修改后的冲突文件加入staging area
git commit #结束merging状态
git push origin exp_branch #记住是origin,注意我们没有权限push upstreamrepository
git checkout master
git push origin master



No comments:

Post a Comment