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 origin和git merge master origin/master
  1. 在terminal中输入git pull origin master,如果我们不知道其他协作者都做出了什么改变,那么分别使用git fetch和git 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 log和git status都是本地执行的命令。如果我们使用git log origin/master,查看到的不是位于GitHub上master 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 request,GitHub以及无法自动合并了,同意pull request按钮便灰。这时需要我们手动解决冲突才能让GitHub上的同意pull request按钮便绿。
  1. 先切换到master分支
  2. 在terminal中输入git pull origin master,如果我们不知道其他协作者都做出了什么改变,那么分别使用git fetch和git merge能使我们在merge前有检查别人改变的机会
  3. master分支成功更新,此时再切换回exp分支
  4. 使用git merge master exp,Git提示我们自动合并失败,检测到合并冲突并告诉我们有哪些冲突文件,此时我们在在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 3和scenario 4我们可以看出,本地工作在master分支时,我们只需要简单的pull和push来更新本地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 fetch和git merge,但有时候git pull不会像git fetch和git merge产生merge commit,这时为什么呢?是因为产生了fast-forward merges,如果我们merge两个commits,假设是a和b,其中a正好是b的ancestor,那么就会发生fast-forward merge,因为a包含b的全部历史commit信息。
注意:我们说a是b的ancestor意思是从版本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_branch在GitHub上更新出一个新的分支
  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 master。pull request应该是交流changes时唯一使用的工具,否则大家都使用git push的话,有些人还没注意到呢,remote master分支就已经改变了,这是非常不好的

添加Original repository为本地clone的remote

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






  1. 首先将Original的repository设置为remote的upstream
git remote add upstream http_url
  1. 更新本地clone的master分支与Original的master分支一致
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 upstream的repository
git checkout master
git push origin master



Thursday, March 3, 2016

GitHub 使用指南 Part I


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

设置密码缓存(Password caching)

如果克隆GitHub的repository时使用了HTTPS链接,那么我们可以通过设置credential helper暂存我们的GitHub账号和密码。注意:Git的版本必须大于1.7.10才能使用credential helper。
  1. terminal下输入git config --global credential.helper cache以开启设置开启credential helper 缓存
  2. 默认情况下 credential.helper 会缓存15分钟,通过terminal下输入git config --global credential.helper 'cache –timeout=3600' 修改默认timeout,此处设置为3600分钟

PUSH:将本地repository同步至GitHub

登陆GitHub账号,创建新的repository,repository名与本地repository名一致,但是不要初始化README。新建repository时初始化README相当于一次commit,这样就可以从GitHub把新建的repository克隆至本地。如果本地已经有repository,目的是把本地同步至GitHub,那么就没有必要初始化README文件。
  1. 登陆GitHub账号,创建与本地repository名一致的repository
  2. 本地terminal下使用git remote查看当前目录的追踪信息,由于我们还没有将本地目录与GitHub目录关联,git remote输出为空
  3. terminal下输入git remote add origin http_url,其中 http_url为GitHub目录页面上显示的HTTPS链接,由于我们只与一个GitHub目录关联,这个目录我们起名为origin
  4. 再次使用git remote查看当前目录的追踪信息,输出显示origin。再使用git remote -v显示verbose信息,这时候我们可以看到分别用于fetch和push的目录,一般情况的这两个目录是一致的
  5. terminal下输入git push origin完成把本地commit上传至GitHub

PULL:将GitHub的最新更改同步到本地

当GitHub上的repository比本地repository版本更新时,我们想要将GitHub上的repository同步到本地,这该怎么做呢?
在terminal下输入git pull origin master便可以将origin目录下的master branch同步到本地
注意:git pull origin master后本地working directory,本地staging area和本地master branch都会改变

FORK:GitHub上将别人的repository复制到自己的GitHub

在GitHub找到好的项目想在本地编辑的同时又不想影响到别人的project该怎么办?
  1. 首先在GitHub上别人repository的页面上点击Fork,从而将别人的repository复制到自己的GitHub的repository中,这个复制过来的repository称作fork
  2. 在terminal中使用git clone http_url将fork到自己GitHub上的repository克隆到本地
  3. 使用git remote -v查看目录追踪状态,我们发现Git已经帮我们配置好了位于GitHub上的fetch和push的目录。这是因为我们使用git clone时,Git自动帮我们设置了指向克隆对象的指针(remote pointing)
  4. 此时我们可以在本地更改克隆到本地的目录中的文件,更改完成后不要忘了git add modified_file,git commit,git push origin。最后一步将本地修改同步至我们的GitHub中,但是不会影响别人GitHub的repository

Clone,Branch和Fork

可以通过git branch -a 来查看本地远程所有分支,当然输出信息不一定是up to date的