How to Use Git and GitHub(二)

Lesson 3: Using GitHub to Collaborate

3.1 Creating a GitHub Account

Set up Password Caching

Every time you send changes to GitHub via the command line, you'll need to type your password to prove that you have permission to modify the repository. This can get annoying quickly, so many people like to set up password caching, which will let you type your password once and have it auto-filled on that computer in the future. To do this, follow the instructions here. If you're using Windows and you followed our Git installation instructions earlier, you're using msysgit, so you can follow the instructions for msysgit.

3.2 Keeping Repositories in Sync

在向github推送前,一定要先把working directory and staing area里的文件commit掉, 通過commit history記錄下來。

web110.png-108.7kB
web110.png-108.7kB

github repo里沒有working directory and staing area, 因為github repo 是在遠程的,并不能直接連接,所以沒有。github不會像其他service一樣sync with cloud,比如CMD markdown就是,我現(xiàn)在敲擊的每一句話都會立刻與云端同步。而且正因為能自動同步到云端,when you use Github, you need to choose when and how to get two version.

So, since syncing doesn't happen automatically, how do we sync between the local copy of a repository and the one hosted on GitHub?

你可能回答lesson oneli里用過的git clone.但這個命令只能從github server clone, 并不能把本地的repo clone 到github server上。

git has a concept of a remote repository. This lets you store the location of a repository that you will want to send and receive new commits to and from. Git users often refer to these remote repositories simply as remotes.
我們在之后的課程里再詳細講這個remote repository

假設(shè)我們現(xiàn)在已經(jīng)有了remote repo指向github上的repo(見圖中arrow), you can pull data and push data. 我們不是一個一個的commit推送,而是選定一個branch, git push后,就能把這個branch下的所有commit同步到remote repo。

web111.png-176.9kB
web111.png-176.9kB

但是想象一些,如果branch里有上百個commit,每次push都要把所有commit推送的話是件很低效的事。

web113.png-171.6kB
web113.png-171.6kB

git的做法很聰明,只提交“有用的”branch。比如下圖中l(wèi)ocal有4個branch, github里只有一個branch. 現(xiàn)在我要推送local 里的a, 即e53,github會找到這個e53的所有parent和children。并只推送github中沒有的branch. 而664因為unreachable,所以不會被推送。所以結(jié)果只有fd2 and e53被推送。

web114.png-145.8kB
web114.png-145.8kB

3.3 Adding a Remote

我們打算把local 的 reflection 推送到github. 先cd到reflection directory。

記住,remote repo的stardard name 是origin. 用git remote add origin url_address,url_address可以在創(chuàng)建好的github repo里找到,初始化不帶。

git remote add origin https://github.com/user_name/reflections.git
web116.png-75.9kB
web116.png-75.9kB

我自己嘗試推送的時候得到了error

[XX@XXXX] ~/Udacity/version-control/reflections  
? git push
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

發(fā)現(xiàn)這個reflections derectory根本沒有初始化。

初始化以及準(zhǔn)備工作: git init, git add xxx.txt,git commit -m "add xxx.txt.

好了,創(chuàng)建remote: git remote add origin https://github.com/user_name/reflections.git
git remote能查看remote branch. git remote -v能查看更多的信息。

git push takes two arguments, the remote I want to send changes to, and the name of local branch that I'd like to push. 所以把branch master push到 remote origin.

git push origin master
web119.png-95.1kB
web119.png-95.1kB

命令行提示輸入github的用戶名和密碼,輸入后推送完成,可以在github官網(wǎng)上看到相應(yīng)的文件了。
推送后,github默認會創(chuàng)建相同的branch name,即github上的branch也叫master。

3.4 Editing Files on GitHub

點擊commit button,可查看commit history. 點擊new fiel創(chuàng)建一個新文件。填寫文件名,文件內(nèi)容,commit message等相關(guān)信息。

web120.png-31.3kB
web120.png-31.3kB

我們在github直接創(chuàng)建一個文件,比如collebrate的時候別人也會上傳一些commit,而我們的本地主機沒有相關(guān)文件。下一節(jié)練習(xí)如何得到最新的version。

3.5 Pulling Changes

這是我們現(xiàn)在的狀態(tài)


web121.png-144.8kB
web121.png-144.8kB

利用git pull來獲得最新的commit

web122.png-166.8kB
web122.png-166.8kB

在terminal端的操.git pull后還是要two argus, 一個是remote name, 一個是本地的branch name.

git pull origin master

pull之后,branch也會checkout到最新的commit狀態(tài)。

web123.png-65.2kB
web123.png-65.2kB

run git log就能看到在github端提交的commit了。

3.6 Concept Map: GitHub, Push, Pull, Remote

We’ve introduced a few new concepts since we last revisited our concept map.

  • GitHub
  • git push
  • git pull
  • remote

GitHub is a service that lets users interact with Git. But I chose to represent it as Git being a part of GitHub.

A remote in your local repository is basically a reference to another repository, so we can say that remote refers to repositories. Also when you clone a repository, a remote gets set up for you automatically, so we can say that clone operators on remotes.

When you push or pull, you have to specify what branch you want to push or pull. So, it definitely operates on branches. Pull takes a branch from a remote and brings it to your local repository. And push does the opposite, taking a branch and pushing it to a remote. So these do both operate on a remote as well.

web124.png-355.8kB
web124.png-355.8kB

3.7 Forking a Repository

左上是原始的repo,通過fork,會在自己的github賬戶中創(chuàng)建一個相同的repo。而Caroline和Sarah可以對右上的repo做出各種修改,制作自己喜歡的recipe,個人定制化。

git91.png-682.4kB
git91.png-682.4kB

quiz

git92.png-130.3kB
git92.png-130.3kB

左上,Branches happen on a single repository. Of course, you can push and pull branches, but when you create one, you're creating it on one single repository

右上,右下,Cloning involves taking an existing repository and making one just like it. The original repository could either be remote, like in this case, so here we cloned from GitHub to local. Or you could even clone a local repository into another spot on your computer. We haven't really talked about this, so this one was probably a little tricky.

左下,This one looks a lot like a clone too, but remember, we are cloning our repository from GitHub onto GitHub. You do that using GitHub's built-in fork feature. Forking is only used within the context of GitHub, taking an existing GitHub repository and making a copy of it, whereas clone works on any two repositories.

3.7.1 Fork the Recipes Repository

找到想要fork的repo,點擊github頁面右上的fork,這樣你的賬戶里就有一樣的repo了。跳轉(zhuǎn)頁面到你賬戶里的repo,找到右下的https賦值。在本地git clone https//XXX就能得到local repo. 如果是通過這種方式,我們就不用自己添加remote了,git會自動添加remote. 不信的話運行git remote -v查看詳情。

我想讓Larry和我一起collaborate這個repo,在右下的setting里添加collaborator,輸入對方的github name.

3.7.2 Push Changes to the Recipes Repository

Add a new recipe to the repository
On your own computer, add a new recipe for a food that you like and commit it on the master branch.

Push your changes
Push the master branch to your fork.

Where was your commit?

Before you ran git push, your change should have only existed locally via git log. Commits will not automatically be shared to remotes - you have to manually push your branch if you want to share changes.

After you ran git push, your change should have existed locally and on your fork. It should not have existed on Larry's repository, which is the repository you forked. The reason you forked in the first place is because you don't have permission to change Larry's repository!

3.8 Collaborations Cause Conflict

如果local和github上的repo都有了改變,那么不論是pull還是push,都會有confilict.


git94.png-78.6kB
git94.png-78.6kB

其實我們想merge local and remote branches.

3.8.1 Change the Chili Recipe Quiz

最上面的commit是另一個人提交的。


git97.png-120kB
git97.png-120kB

因為兩個人都對同一個文件的同一行做出了改動,github會高亮標(biāo)識,提示有confilct

git98.png-158.6kB
git98.png-158.6kB

3.9 Updating Local Copies of Remote Branches

我對一個Chili Recipe里做了改動后(包括add, commit),本地的master已經(jīng)最新了,但是remote branch還沒有更新。而remote branch的name就是origin/master,通過git push后,才能讓branch master和origin/master同步。不信的話先別push,git diff origin/master master (git diff old_one new_one), 可以看到二者之間的差別。

圖中本地的origin/master和github的master都是未更新狀態(tài),只有l(wèi)ocal的master有改動,是latest.(注:origin和origin/master是一個branch)


git100.png-84.9kB
git100.png-84.9kB

push后,全部更到最新。


git101.png-121.3kB
git101.png-121.3kB

如果現(xiàn)在local和github repo都改變了


git102.png-115.6kB
git102.png-115.6kB

我們可以通過git fetch只更新local, 即讓origin/master和github repo(remote)同步,而讓local的master被保留。

git104.png-127.8kB
git104.png-127.8kB

也就是說,local現(xiàn)在有兩個branch,一個是master,一個是和remote github端同步了的origin/master. 比如說現(xiàn)在我要上飛機,但我本地已經(jīng)有了最新的version,這個時候我可以merge這兩個branch。但我也可以不著急merge二者,繼續(xù)在master做我的修改。

git105.png-128.9kB
git105.png-128.9kB

但如果merge了的話,其實相當(dāng)于用了git pull。因為pull的流程也是先更新(fetch)本地的remote branch origin/master,然后再把origin/master和local的master 合并(merge).
所以說,git pull = git fetch + git merge

git106.png-445.4kB
git106.png-445.4kB

3.9.1 Merging the Changes Together

實操:command line
現(xiàn)在的狀態(tài)是github remote段寫了兩個commit,local段寫了一個commit.

可以用git branch -a看到remote branch. 用git fetch origin把本地的origin/master更到和github remote端一樣新。git log orgin可以查看origin/master的所有commit,現(xiàn)在這個branch的commit已經(jīng)完全和github端一樣了,git log查看的是local的master。

git110.png-64.1kB
git110.png-64.1kB

git status可以看到當(dāng)前的狀態(tài),提示說origin/master和local的master有不同的commit進度

git111.png-32.8kB
git111.png-32.8kB

git merge master origin/master,理所當(dāng)然得得到了conflict提示,因為兩個branch的commit history不一樣

git112.png-18.8kB
git112.png-18.8kB

好了,打開有問題的文件,fix the conflict.
原文件


git113.png-29.1kB
git113.png-29.1kB

我要保留github 段做出的修改


git115.png-22.7kB
git115.png-22.7kB

修改完后,git add xxxx and git commit這一次沒有加message,但是竟然跳出了nano的編輯界面,自動寫好了message. Ctrl+X, 選yes, alt+D選擇DOS-format,即可保存message。果然還是自動的填寫的信息更準(zhǔn)確方便。

git114.png-13.9kB
git114.png-13.9kB

通過commit之后,這次merge也就算成功了。當(dāng)然,也可以直接git pull.
git push origin master,順序不能錯,必須是git push remote_branch local_branch. push后就能在github看到所有的commit了。

3.9.2 Fast-Forward Merges

既然git pull = git fetch + git merge,那為什么在上一節(jié)的例子里,直接用git pull的時候沒有g(shù)enerated merge commit like git fetch + git merge did.

因為啟動了fast-forward merges. This kind of merge occurs when you merge two commits, where one is ancestor of the other. (一個commit是另一個commit的祖先,這里的commit也可以理解為branch)

git117.png-89.9kB
git117.png-89.9kB

如果想把上圖中的a和b合并,其實沒有必要創(chuàng)建一個新的commit。想想也知道新的commit也會有二者共同的commit history, 那么創(chuàng)建一個新的commit就沒有必要了。

git118.png-93kB
git118.png-93kB

只需把commit label 更到最新即可。So instead of adding a new commit, all we would do is update the lable to point b(latest).

git119.png-66kB
git119.png-66kB

We're taking a label from the history of a branch somewhere in its ancestry, and moving that label forward to the tip of the branch.

quiz

git120.png-131kB
git120.png-131kB

3.9.3 Making a Pull Request

其實這里的pull并不是git pull里的意思,而是我打算在github段合并兩個branch,這個合并的申請叫做 pull request, github非要這么設(shè)定,只能順勢而為了。

現(xiàn)在做一個example,展示整個workflow。

  1. 我先在本地修改了cask-recipe.txt里的配方,添加了一種更健康的oil.
  2. 創(chuàng)建一個branch,叫different oil.git branch different-oil+ git checkout different-oil 或者用一個命令git checkout -b different-oil.
  3. git add cask-recipe.txt + git commit + git push origin different-oil. 這樣就把branch different-oil 推送到了github端。接下在就能在github端查看了。
    git121.png-127.6kB
    git121.png-127.6kB
  4. 切換到branch different-oil,查看commit
    git122.png-141.5kB
    git122.png-141.5kB
  5. 我們向pull request, 點擊pull request button(如果綠色的那個button沒出現(xiàn)的話就在branch different-oil里點pull request button,如圖)
    git123.png-102.5kB
    git123.png-102.5kB
  6. github默認會認為你想要和原版的Larry的master合并,但是我們只是想把branch different-oil和master合并而已。點擊右側(cè)的edit,選擇要合并的branch。再點擊右下的create pull request. 這樣我們就發(fā)出了請求。
  7. 現(xiàn)在在pull request里可以看到我們做出的所有commit,修改。其他的人可以在主頁面右側(cè)的list里有pull request,可以點擊查看。
    git124.png-82.5kB
    git124.png-82.5kB
  8. 好了,接下來是另一個contributor的視角了,也就是Sarah.因為Sarah watching Caroline's fork of the recipes repository, 所有Sarah got an email notifying that Caroline made a pull request. 點擊郵件里的地址,查看pull request.
  9. Caroline想讓sarah同意合并maser和different-oil。因為master是最主要的branch,所以必須保證沒有錯誤。Sarah查看了Caroline做出的修改,但是添加的那個oil有拼寫錯誤。所以Sarah在下面的寫一個comment,提醒Caroline發(fā)現(xiàn)的問題。也可以在上面出錯的地方寫一個inline comment
    git126.png-155.6kB
    git126.png-155.6kB
  10. 如果檢查后一切正常,可以點擊merge pull request button. 這個button只有在沒有conflict的時候才會
    git127.png-130.3kB
    git127.png-130.3kB
  11. 在有conflict的情況下,先讓Caroline fix the conflict。讓Caroline合并master和different-oil,成功后說明沒有什么問題,之后再同一merge.

quiz

git129.png-550kB
git129.png-550kB

3.9.4 Updating a Pull Request

  1. 上一節(jié)里Sarah發(fā)現(xiàn)了pull request 里有spell error,所以寫了個comment。接著Caroline收到了郵件,里面寫著comment的內(nèi)容。
  2. Caroline在local檢查了下文件,發(fā)現(xiàn)全是寫錯了,于是fix,然后commit the fix。
    git130.png-67.3kB
    git130.png-67.3kB

    git131.png-179.7kB
    git131.png-179.7kB
  3. git push origin different-oil,這樣github端也能看到修改了。
    git132.png-62.5kB
    git132.png-62.5kB
  4. push branch自動出現(xiàn)在pull request界面,在Sarah的comment下面,能看到Caroline的commit:Fix type in caola.
    git133.png-120kB
    git133.png-120kB
  5. 現(xiàn)在commit顯示為2,file changed顯示1,可以點擊file changed查看修改。
    git136.png-99kB
    git136.png-99kB

3.9.5 Conflicting Changes

前一節(jié)我們學(xué)會了如何pull request,這一節(jié)我們take a look at what happens when someone else makes changes that confilct with your pull request.

Sarah也made a pull request,


git137.png-119.3kB
git137.png-119.3kB

It looks like she increased the amount of oil to put in the cake so that it would be more moist. Since our changes affect the same line, git will mark them as a merge so one of us will have to resolve the conflict.
二人修改的是同一行,所以git認定是一個merge conflict,二人中的一個得負責(zé)fix it.


git138.png-350.7kB
git138.png-350.7kB

點擊左上的conversatoin button,先點擊綠色的merge pull request, 再點擊綠色的Confirm merge, 即先confirm Sarah的changes,然后再去resolve merging conflict。

git139.png-393.8kB
git139.png-393.8kB

Confirm后就可以刪除sarah創(chuàng)建的more-oil branch 了。

git140.png-257kB
git140.png-257kB

回到pull request 界面,發(fā)現(xiàn)無法merge的消息提醒。This is because performing a merge between the master branch and my branch would now cause merge conflicts. 之前的Sarah的修改已經(jīng)提前改變了master里的cake-recipes.txt里的oil那一行,而Caraline在自己的branch里也是修改的同一行,所以無法合并master,有confilit.

git141.png-88.4kB
git141.png-88.4kB

解決方法:Rather than having you resolve the merge conflicts from the browser GitHub requires you to merge the changes on your own computer and send update the pull request with the merged version.
也就是說github不讓你通過browser更改,必須要在local fix conflict, merge suffessfullly, then git push to update the merged version.

圖解

初始狀態(tài):左圖是local version,master在中間,Craline做出的changes全在新的branch different-oil里。右圖是github version. 可以看到中間是master,但是從master開始,向右有兩個branch就有差異了。一個右上角Sarah做出修改的branch more-oil,一個是右下角Craline做出的changes的branch different-oil。

git142.png-493.4kB
git142.png-493.4kB

我們把master和Sarah的more-oil branch合并。這其實本來是個fast forward merge, 也就是說master的lable會移動到more-oil上,并不會創(chuàng)建一個新的commit。但是github的merge機制不一樣,只要是github頁面上的merge button,點擊后merge后就一定會有一個commit。(it turns out that even if you could of had a fast forward merge, merging with the button on GitHub will always make a commit anyway even if no extra information is given by making that merge commit.) 合并后master label 到了新的commit上。現(xiàn)在就可以刪除more-oil這個branch了,因為一旦合并它的使命也就完成了。所以在圖中把右上角的more-oil這個branch name 移去。現(xiàn)在Craaline想要把自己的branch和master合并,但因為兩個人都對同一line做除了改動,所以有conlict. 現(xiàn)在Caraline必須在local fix this conflict.

git143.png-476.6kB
git143.png-476.6kB

Now if Caroline wants to update her pull request to include my changes. If merging these two branches wouldn't cause a conflict, I could actually just pull in her request now. But since we changed the same lines, she's going to have to pull these changes over into her local version. So she'll need to pull master.
要想在local修改,就要用git pull更新本地到最新版本。

git144.png-561.1kB
git144.png-561.1kB

好了,現(xiàn)在Caraline可以直接fix conflict,merge master and different-oil, git push, 這樣github段的master就能更新了。但是!!!這么做的話其他人沒有機會看到Caraline做出的修改,也沒有機會提醒修改是否合理。尤其是在collaboration的環(huán)境下,必須要讓別人review,所以要通過github的pull request功能來提交,這樣其他人就能得到通知,來查看修改是否正確了。

具體的做法: Caroline will need to make the fix to her branch. Fix the typo for canola, and then merge in master into her different oil branch. And then push her branch up to GitHub which will update the pull request so that I can look at that before merging it back into master.
也就是說把所有改動放在different-oil里,然后合并masterdifferent-oil, 再push different-oil,github那邊會自動更新 pull request. 注意,別把different-oil合并到master,然后推送master,這會直接覆蓋,別人沒有機會在merge前review。

git145.png-600.1kB
git145.png-600.1kB

3.9.6 Updating Your Local Repository

上一節(jié)講了各種原理,這一節(jié)講在terminal端的具體命令操作。

git pull origin master更新local. 也可以用git fetch + git merge origin master.

git146.png-91.3kB
git146.png-91.3kB

先checkout到different-oil,再git merge master different-oil.這樣才能把master merge到branch。如我們所料,得到了merge conflict提示。

git147.png-92.2kB
git147.png-92.2kB


下面是stackoverflow上的回答:
How to merge the master branch into the feature branch? Easy:

git checkout feature1
git merge master

I'll resolve the conflict keeping both of our changes, so now there's three quarters of the cup of canola oil, and then I'll commit the merge.
修改了cake-recipes.txt后,commit.

git148.png-178.7kB
git148.png-178.7kB

Now I'll run git log, and I can see that this branch contains both of our changes.
這下兩個人的修改commit就都能看到.

git149.png-521kB
git149.png-521kB

之后run git push origin different-oil。As you saw before, pushing the branch updates the pull request.
push后就能更新github端的pull request了

git150.png-406.6kB
git150.png-406.6kB

在點擊綠色的Merge pull request前,先寫個comment通知Sarah讓她來review.因為updata the pull request的消息是不會email給Sarah的。

git151.png-117kB
git151.png-117kB

quiz

git152.png-73.8kB
git152.png-73.8kB

After running git log -n 1, you should have seen output something like this:

commit bc368511c6406028c77e2631f77c4d22a5da16d0
Merge: 79fff84 23d1775
Author: cbuckey 
Date:   Tue Sep 30 18:50:28 2014 -0400

    Merge pull request #1 from cbuckey-uda/different-oil

    Change vegetable oil to canola oil

Notice that the commit message:

  • Indicates that a pull request was merged
  • Gives the number of the pull request (#1 here)
  • Gives the branch the pull request was merged from (cbuckey-uda/different-oil here).
  • Contains the title of the pull request.

GitHub automatically creates a commit message like this whenever a pull request is merged to make it easy to see pull requests in the commit history. Even when the merge is a fast-forward merge, GitHub still creates this commit.

3.10 CM: Fork, Fetch, Pull Request

git154.png-539.1kB
git154.png-539.1kB
git156.png-514.3kB
git156.png-514.3kB

Forking is like cloning but with some extra steps and you can only do it on GitHub itself. It also takes a repository and makes another repository, so it does operate on repositories.

We know that fetching is a part of pull, but does it operate on remotes and branches? It clearly operates on remotes, because you're fetching data from the remote repository. The connection to branch is a little less clear. You can definitely, fetch a particular branch. When you fetch, the branch doesn't necessarily get updated. But remember that, we have references to the remote versions of our branches, and those are the things that get updated. So, it does operate on branches, as well.

you would think fast-forward merge would be related to merges.But the way that I think, about fast-forward merges is basically, that they change where a branch points. So, it's take a branch label from one commit to another commit. So in my mind, it just operates on a branch.

When you make a pull request, you're asking to have a particular branch be merged in, with the main branch or some other branch. It doesn't necessarily, have to be a master. And pull requests are purely GitHub idea. They don't exist in git proper. So, mergers are part of pull requests. Pull requests, work on branches. You merge two branches together. And it's something that's part of GitHub, so it all fits.

3.11 Reflect: When to use a separate branch

You just saw that the workflow when making changes in a separate branch is more complicated than working directly in master, especially when you need to stay up-to-date with changes others are making. Rather than simply pulling and pushing, you need to pull changes into your local master branch, merge the local master into your branch (different-oil, in our case), then push your branch to the remote before finally merging your branch into master, either locally or on GitHub.

Given that, please add the following question and your thoughts on it to your reflections file:

When would you want to make changes in a separate branch rather than directly in master? What benefits does each approach have?

因為通過創(chuàng)建不同的branch來添加新的feature更易于和別人合作,每個人都更易于理解project的branch結(jié)構(gòu),user friendly. 通過pull request來merge,也能讓別人review。

3.12 Modifying the Adventure Repository (實操練習(xí))

以下是指南部分,主要是fork這個repo,來進行練習(xí)。
Fork the repository and clone your fork

Now that you've learned how to fork a repository, push changes to your fork, and make a pull request, you’re ready to contribute to the create-your-own-adventure story that you saw at the beginning of the lesson. To do this, first you should fork this repository. Then clone your fork, and make a branch to make your changes in.

Note: You could make your changes directly to the master branch in your fork, but when contributing to a public repository, it’s standard practice to make the changes in a non-master branch within the fork. This way, you can easily keep your master branch up-to-date with master of the original repository, and merge changes from master into your branch when you are ready.

Make a change to the story

Next, you should actually make a change to the story. For instructions on how to do so, please read the README in the create-your-own-adventure repository.

Make a pull request

Next, you should make a pull request containing your changes to the original repository. To do this, click the "pull request" button from your branch like you did before, but this time, leave the original repository as the base.

Ask for your pull request to be merged

You don't have permission to modify this repository, so you'll need someone at Udacity to merge your pull request. Our helpful bot Casey may be able to merge your pull request automatically. To have your pull request automatically merged, you'll need to follow the guidelines in the README of the repository, and in addition you won't be able to delete or modify lines. That restriction on deletions is because Casey doesn't want to merge a request that accidentally deletes part of the story, and she can't tell the difference between an accidental deletion and an intentional modification. To request auto-merging, leave a comment on the pull request containing "@casey-collab". For example "Please review this, @casey-collab". Make sure to leave the comment on the "Conversation" tab of the pull request, not the "Files changed" tab.

There are some valid pull requests that Casey won't be able to merge. For example, she won't accept a pull request that fixes a typo, since that modifies a line. If you'd like to make a pull request Casey can't merge, feel free to do so, and someone from Udacity will merge the pull request if we have time. However, we can't guarantee a response to these pull requests.

If needed, update your pull request

If someone merges your pull request or leaves a comment, GitHub will email you and let you know. If you're asked to make some changes, push those changes to your fork to update the pull request. Make sure you let the reviewer know that they should take another look!

If your pull request would result in a merge conflict, and you're not sure how to resolve it, see the next video for instructions.


根據(jù)上面的指南,完成了整個練習(xí)。review一下整個流程:

  1. github(original): fork repo create-your-own-adventure.在我的repo里得到github (my fork): create-your-own-adventure
  2. local(terminal): git clone github (my fork): create-your-own-adventure。在本地得到了整個repo
  3. local(terminal): 在/create-your-own-adventure/chinese/里添加了folder little_prince,在floder里添加了file:this_is_a_story_about_a_boy.md.這個path: create-your-own-adventure/Chinese/little_prince/this_is_a_story_about_a_boy.md. git checkout -b little-prince,創(chuàng)建新的branch. git add xxx+git commit -m "xxxxx", 最后git push origin little-prince
  4. github(my fork): 有了新的branch,點擊comment&pull request綠色button.這一次合并請求的對象是github(original)里的那個master, 被合并的是github(my fork)下little-prince這個branch. 點擊綠色的commit pull request
  5. github(original):打開Pull request(有80+ge), 移動到Conversation這個label下,只有在這里留言才能提醒original repo的owner去處理我的合并請求。在comment里留言@casey-collab.這個是一個bot,查看你的提交是否符合規(guī)范
  6. local(terminal):好了,看來不符合。@casey-collab 給我反饋說md文件里的一行太長,超120個字符,讓我用回車隔開。還有一個問題是在chinese/language.md里應(yīng)該添加一行鏈接到我的文件,不然如果別人直接看language.md的話,是看不到的我的文件的。所以我在大話西游.md里添加了一行[little_prince](little_prince/this_is_a_story_about_a_boy.md)。(我想吐槽一句,能不能別用大話西游.md表示language.md,看了好久沒反應(yīng)過來)
  7. local(terminal):修改完了。 git add 兩個文件_分別add,'git commit'(注釋用自帶的,自己寫的不好),git push origin little-prince.
  8. github(original):Pull request, 移動到Conversation這個label下,再給@casey-collab寫個comment告訴他我改好了。@casey-collab告訴我好了,沒問題了。會自動merge pull request. 這個時候有提示,可以刪除little-prince這個branch了。
  9. local(terminal): git checkout master, git merge little-prince, git push origin master.
  10. github(original):好了,這樣在主目錄里就能看到自己添加的文件了。而github(my fork)里也會有最新的commit和文件。Over

3.13 Keeping a Fork Up-To-Date(Merge Conflicts in Pull Request)

有時候pull request會因為merge confilcts無法通過。比如,你fork了一個repo,你在fork repo上做了changes,但是此時original repo也有別人做了修改,所以pull request會有merge conflicts, 而且你是沒有權(quán)限修改origianl repo的。在github端使無法解決這個conflict,必須得在local解決。下面說得更具體些:

初始狀態(tài)


git157.png-113.2kB
git157.png-113.2kB

然后在local做了些changes,并把這些push到了fork repo.


git157.png-113.2kB
git157.png-113.2kB

與此同時有人更新了original repo。所有現(xiàn)在問題出現(xiàn)了,你想把自己的fork repo和original repo 合并,但因為現(xiàn)在兩個repo都有了變化,所以pull request會有merge confilct。(If there are merge conflicts between their change and your change, then your pull request will not be able to be automatically merged.)


git159.png-110.4kB
git159.png-110.4kB

Since there's no way to resolve merge conflicts on the GitHub site, you'll need to resolve the conflicts within the clone on your computer.
因為不能在github端解決conflict, 所以必須要把conflict clone到local來解決。也就是說,一個是local的已經(jīng)有了changes的branch,這個branch和fork repo是一致的,另一個是已經(jīng)更新過的latest origial repo,我們想把后者clone到local,在local合并并解決conflict后再push就能解決問題了。那么如果把original repo clone到local呢? 我們可以通過adding remote(這里的remote就是original repo)的方式來做到這點。(To do that, you'll need to get the conflicting changes from the original repository into your local repository, which you can do by adding a remote.)

但是別忘了我們已經(jīng)添加了一個remote叫origin,這個origin指向fork repo,我們需要另一個remote指向original repo。通常,這個指向original repo的remote起名為upstream。(Recall that you already have a remote set up called origin that points to your fork. But you'll still need to add a remote that points to the original repository. And many people namethis remote upstream.)

在本地fetch創(chuàng)建新的branch后,這個新的remote 的正式表示是 upstream/master。這樣就可以在本地把upstream/master和local branch合并了。(Adding and fetching the upstream remote will add branches like upstream/master into your local repository, so that you can merge the upstream branch with your local branch.)


git160.png-331.6kB
git160.png-331.6kB

現(xiàn)在我們舉例來說。original repo里添加了名為Sprikler的branch,而我在本地做出的changes也全放到了名為stop drop roll的branch里。

git161.png-136.3kB
git161.png-136.3kB

在local,因為我們把changes都放在新的branch stop drop roll里了,所以我們想把master更新到original repo的最新版。git merge upstream/master master.(Since I created my change in a separate branch, I want to make my master branch the same as the master in the original repository. So, I'll run git pull upstream/master to update my master branch to the latest commit from the original repository.)

git161.png-136.3kB
git161.png-136.3kB

git162.png-43.8kB
git162.png-43.8kB

然后我們把master和stop drop roll branch(也就是我們在本地change過的branch)合并成change branch。

git163.png-45.5kB
git163.png-45.5kB

然后把master和change branch都推送到fork repo。(Then I'll merge the master branch into my changed branch, and I'll push both the changed branch and the master branch to my fork. I didn't need to push the master branch, but I thought it might be nice.)


git164.png-163.5kB
git164.png-163.5kB

quiz

git165.png-101kB
git165.png-101kB

實操

  1. 復(fù)制original repo 的https, 作為remote添加到local。
    git167.png-51.2kB
    git167.png-51.2kB
  2. 切換到master,然后用git pull upstream master更新master
    git168.png-39.8kB
    git168.png-39.8kB
  3. 此時用git log就能看到最新的commit了
    git169.png-244.3kB
    git169.png-244.3kB
  4. 切換到stop-drop-roll branch,也就是我們在local做出了changes的branch。然后和master合并,這樣就得到了merge conflict.(記住,想要把A合并到B里,就先checkout到B,在進行merge)
    git170.png-41.8kB
    git170.png-41.8kB
  5. 得到conflict后打開文件,fix the conflict
    git173.png-191.3kB
    git173.png-191.3kB
  6. git add xxxx,git commit,git push origin stop-drop-roll,記住最后是把stop-drop-roll push 到 origin,也就是fork repo,而不是original repo. 因為你沒有權(quán)限直接推送給主倉庫。
    git175.png-57.8kB
    git175.png-57.8kB
  7. 然后checkout到master,把master也推送到fork repo
    git178.png-50.8kB
    git178.png-50.8kB
  8. 好了,解決了conflict,回到全球同性交友網(wǎng)站,發(fā)現(xiàn)可愛的綠色button,說明我們能merge pull request了。
    git179.png-133.2kB
    git179.png-133.2kB
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 因為原文太長超出字?jǐn)?shù),Lesson 3 就放在另一篇文章里 How to Use Git and GitHub 標(biāo)...
    赤樂君閱讀 5,272評論 1 5
  • origin websiteComparing WorkflowsCentralized Workflow Fea...
    伍帆閱讀 524評論 0 0
  • 我從來都沒有感覺自己有愛你, 你準(zhǔn)備離開的當(dāng)天天。 平時賣火腿腸的老奶奶問:那個男孩子呢。 我開心說:奶奶你好久都...
    馬櫻佳閱讀 465評論 0 1
  • 喜歡寫字,從十幾歲開始。那時,第一次離開家,去很遠的城市。陌生的環(huán)境,陌生的人,內(nèi)心的孤獨,讓性情安靜的我更孤僻。...
    微笑的小魚閱讀 339評論 0 0
  • 推薦一個正則表達式的開源測試工具 接下來的demo都會使用這個工具進行測試: https://github.co...
    螞蟻牙齒不黑閱讀 564評論 0 0