1. 假定原作者的名稱叫g(shù)ittest, 我叫uniquejava.
原作者新建了一個(gè)項(xiàng)目叫nocrazy。 于是路徑為gittest/nocrazy 做了兩次提交 提交一: a.txt this is a 提交二:b.txt this is b.
2. 我cyper某天fork了這個(gè)項(xiàng)目,于是有origin指向uniquejava/nocrazy, 并且新增一個(gè)upstream指向原作者gittest/nocrazy $ git clone https://git.oschina.net/uniquejava/nocrazy.git $ cd nocrazy nocrazy git:(master) $ git remote add upstream https://git.oschina.net/gittest/nocrazy.git nocrazy git:(master) $ git remote -v origin https://git.oschina.net/uniquejava/nocrazy.git (fetch) origin https://git.oschina.net/uniquejava/nocrazy.git (push) upstream https://git.oschina.net/gittest/nocrazy.git (fetch) upstream https://git.oschina.net/gittest/nocrazy.git (push) nocrazy git:(master) $ 3. gittest正常提交了一個(gè)新版本 c.txt this is c git log --oneline e63667b this is c 11f5850 this is b 1cbdb56 this is a
4. Cyper想把fork同步到和gittest一模一樣,怎么辦? 辦法一(思考未試驗(yàn)):把自己的fork刪除重新fork? 然后呢在本地git pull origin master 辦法二: git fetch upstream git checkout master git merge upstream/master 方法二需要push才能到origin么。(yes) nocrazy git:(master) $ ll total 16 drwxr-xr-x 13 cyper staff 442B Aug 26 05:11 .git/ -rw-r--r-- 1 cyper staff 10B Aug 26 05:07 a.txt -rw-r--r-- 1 cyper staff 10B Aug 26 05:07 b.txt nocrazy git:(master) $ git fetch upstream remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From https://git.oschina.net/gittest/nocrazy * [new branch] master -> upstream/master nocrazy git:(master) $ git diff ..upstream/master diff --git a/c.txt b/c.txt new file mode 100644 index 0000000..5da75cf --- /dev/null +++ b/c.txt @@ -0,0 +1 @@ +this is c 使用以上git diff命令可以看到author新增了一個(gè)c.txt文件。 nocrazy git:(master) $ git merge upstream/master Updating 11f5850..e63667b Fast-forward c.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 c.txt nocrazy git:(master) $ git status On branch master Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits) nothing to commit, working directory clean nocrazy git:(master) $ git fetch upstream nocrazy git:(master) $ git merge upstream/master Already up-to-date. nocrazy git:(master) $ git diff ..origin/master diff --git a/c.txt b/c.txt deleted file mode 100644 index 5da75cf..0000000 --- a/c.txt +++ /dev/null @@ -1 +0,0 @@ -this is c 通過以上可以看到git merge只是把upstream上的代碼拉到(本地工作目錄+本地倉(cāng)庫(kù)),需要我們push origin nocrazy git:(master) $ git push origin master Username for 'https://git.oschina.net': uniquejava Password for 'https://uniquejava@git.oschina.net': Counting objects: 3, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 292 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To https://git.oschina.net/uniquejava/nocrazy.git 11f5850..e63667b master -> master nocrazy git:(master) $ ll total 24 drwxr-xr-x 14 cyper staff 476B Aug 26 05:21 .git/ -rw-r--r-- 1 cyper staff 10B Aug 26 05:07 a.txt -rw-r--r-- 1 cyper staff 10B Aug 26 05:07 b.txt -rw-r--r-- 1 cyper staff 10B Aug 26 05:14 c.txt 到這里, 步驟4驗(yàn)證結(jié)束。。。成功的將fork上的代碼更新到最新版。 5. 假設(shè)上一步成功執(zhí)行, 效果應(yīng)該和我重新fork一遍最新的項(xiàng)目是一樣的。
6. 重復(fù)3:即gitetst提交了一個(gè)新版本 d.txt this is d.
7. 在6之前,Cyper因?yàn)橐迯?fù)defect #1, 已經(jīng)開始基于c.txt做修改。就沒有來得及及時(shí)同步 cyper修改this is c變成this is c_cyper 然后正常的add, commit , (Cyper此時(shí)是否可以push?) nocrazy git:(master) ? $ git commit -m "[nocrazy-1] fix c." [master 77fd57f] [nocrazy-1] fix c. 1 file changed, 1 insertion(+), 1 deletion(-) 此時(shí)已經(jīng)有了分歧。gittest上有新的提交, cyper也有新的提交。 cyper想基于最新的代碼重新提交。 7-1 假定cyper沒有push 他想先更新fork,然后基于 author最新的代碼去做提交 git fetch upstream git checkout master git merge upstream/master 這一步是用git rebase upstream/master還是用git merge upstream/master ===== nocrazy git:(master) $ git rebase origin/master(這步只是想驗(yàn)證base到當(dāng)前base的情況,無效果) Current branch master is up to date. nocrazy git:(master) $ git fetch upstream remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From https://git.oschina.net/gittest/nocrazy e63667b..380a8dd master -> upstream/master nocrazy git:(master) $ git rebase upstream/master First, rewinding head to replay your work on top of it... Applying: [nocrazy-1] fix c. nocrazy git:(master) $ git status On branch master Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working directory clean nocrazy git:(master) $ 以上這步做了什么???原來git rebase upstream/master把upstream上的代碼拉到(本地工作目錄+本地倉(cāng)庫(kù)),并且自動(dòng)做了合并, 所以你的本了一下子多出來兩個(gè)commit需要push, 因此有Your branch is ahead of 'origin/master' by 2 commits. nocrazy git:(master) $ git log --oneline 8530647 [nocrazy-1] fix c. 380a8dd this is d e63667b this is c 11f5850 this is b 1cbdb56 this is a 現(xiàn)在只需做push origin。。。就行了! nocrazy git:(master) $ git push origin master Username for 'https://git.oschina.net': uniquejava Password for 'https://uniquejava@git.oschina.net': Counting objects: 6, done. Delta compression using up to 8 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 566 bytes | 0 bytes/s, done. Total 6 (delta 1), reused 0 (delta 0) To https://git.oschina.net/uniquejava/nocrazy.git e63667b..8530647 master -> master 所以在發(fā)pull request 之前不要去做push . (如果在rebase之前就做了push,需要怎么補(bǔ)救???) 到目前為止,cyper的遠(yuǎn)程倉(cāng)庫(kù)中是最新的代碼,而原作者的代碼不新,因?yàn)樗拇a沒有包含你的修改 8. 發(fā)pull request 8-1, 假設(shè)gittest在你發(fā)pull request前,沒有提交任何代碼。。 過程很簡(jiǎn)單。 接下來gittest review,他點(diǎn)擊某個(gè)代碼變動(dòng)行的前面加了一個(gè)comment: 少了一個(gè)標(biāo)點(diǎn)符號(hào) 。。 如果你此時(shí)使用git fetch upstream會(huì)沒有任何輸出 然后你 nocrazy git:(master) $ git rebase upstream/master Current branch master is up to date. 這是因?yàn)槟惝?dāng)前沒有任何commit是需要rebase的, 因?yàn)樗衏ommit都已經(jīng)push到了origin. 除非。。 與時(shí)同時(shí), gittest正常添加了一個(gè)新文件 e.txt this is e. 你重新fetch, nocrazy git:(master) $ git fetch upstream remote: Counting objects: 5, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From https://git.oschina.net/gittest/nocrazy 380a8dd..fd2e641 master -> upstream/master nocrazy git:(master) $ git diff ..upstream/master diff --git a/c.txt b/c.txt index 3af12b3..5da75cf 100644 --- a/c.txt +++ b/c.txt @@ -1 +1 @@ -this is c_cyper +this is c diff --git a/e.txt b/e.txt new file mode 100644 index 0000000..5641475 --- /dev/null +++ b/e.txt @@ -0,0 +1 @@ 可以看到,當(dāng)前你的本地倉(cāng)庫(kù)和upstream的區(qū)別是。。你改了c文件而upstream加了e文件。。 你重新rebase nocrazy git:(master) $ git rebase upstream/master First, rewinding head to replay your work on top of it... Applying: [nocrazy-1] fix c. nocrazy git:(master) $ git status On branch master Your branch and 'origin/master' have diverged, and have 2 and 1 different commit each, respectively. (use "git pull" to merge the remote branch into yours) nothing to commit, working directory clean nocrazy git:(master) $ 這時(shí)和第一次有所不一樣, nocrazy git:(master) $ git log --oneline 8c4c4b6 [nocrazy-1] fix c. fd2e641 this is e 380a8dd this is d e63667b this is c 11f5850 this is b 1cbdb56 this is a 查看一下有什么不一樣 nocrazy git:(master) $ git diff ..origin/master diff --git a/e.txt b/e.txt deleted file mode 100644 index 5641475..0000000 --- a/e.txt +++ /dev/null @@ -1 +0,0 @@ -this is e 是因?yàn)槟阕约旱倪h(yuǎn)程倉(cāng)庫(kù)沒有包含e文件。。。按照提示。 你需要做一次pull 但是pull會(huì)產(chǎn)生分支 。。 嘗試一下然后立馬撤銷(http:///questions/1223354/undo-git-pull-how-to-bring-repos-to-old-state) nocrazy git:(master) $ git pull Merge made by the 'recursive' strategy. nocrazy git:(master) $ git log --oneline 9d7a324 Merge branch 'master' of https://git.oschina.net/uniquejava/nocrazy 8c4c4b6 [nocrazy-1] fix c. fd2e641 this is e 8530647 [nocrazy-1] fix c. 380a8dd this is d e63667b this is c 11f5850 this is b 1cbdb56 this is a nocrazy git:(master) $ git status On branch master Your branch is ahead of 'origin/master' by 3 commits. (use "git push" to publish your local commits) nothing to commit, working directory clean 可見, git pull生成的commit history多么的混亂!(相對(duì)于當(dāng)前的origin/master, 一下子多出了3條commit history) 9d7a324 Merge branch 'master' of https://git.oschina.net/uniquejava/nocrazy 8c4c4b6 [nocrazy-1] fix c. fd2e641 this is e 趕緊撤銷并換成git rebase nocrazy git:(master) $ git show HEAD commit 9d7a324e5e562475b9585ed029817fc98d09a1d4 Merge: 8c4c4b6 8530647 Author: cyper <345343747@qq.com> Date: Wed Aug 26 06:11:07 2015 +0800 Merge branch 'master' of https://git.oschina.net/uniquejava/nocrazy 原來。。HEAD并不是指向遠(yuǎn)程倉(cāng)庫(kù)的head.. nocrazy git:(master) $ git show head nocrazy git:(master) $ git show HEAD nocrazy git:(master) $ git show master nocrazy git:(master) $ git show origin/master 。。。前三個(gè)信息都是指向本地倉(cāng)庫(kù)的頭,是沒一個(gè)commit id.最后一個(gè)是我想要的頭,是我pull之前的commit id 所以有三種方法 git reset --hard HEAD^3 或git reset --hard origin/master 或者git reset --hard 8530647b
重做第7步。。 nocrazy git:(master) $ git rebase upstream/master First, rewinding head to replay your work on top of it... Applying: [nocrazy-1] fix c. nocrazy git:(master) $ git status On branch master Your branch and 'origin/master' have diverged, and have 2 and 1 different commit each, respectively. (use "git pull" to merge the remote branch into yours) nothing to commit, working directory clean nocrazy git:(master) $ 現(xiàn)在因?yàn)楸镜貍}(cāng)庫(kù)才是最新的。。你需要force push到origin而不需要理pull操作。。。 nocrazy git:(master) $ git push origin master --force Username for 'https://git.oschina.net': uniquejava Password for 'https://uniquejava@git.oschina.net': Counting objects: 6, done. Delta compression using up to 8 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 569 bytes | 0 bytes/s, done. Total 6 (delta 1), reused 0 (delta 0) To https://git.oschina.net/uniquejava/nocrazy.git + 8530647...3e23afc master -> master (forced update) git rebase產(chǎn)生了完美的commit history: 3e23afc [nocrazy-1] fix c. fd2e641 this is e 380a8dd this is d e63667b this is c 11f5850 this is b 1cbdb56 this is a
|