背景
在開(kāi)源大項(xiàng)目中,不能直接對(duì)目標(biāo)項(xiàng)目進(jìn)行改動(dòng),需要先f(wàn)ork一份到自己的倉(cāng)庫(kù)進(jìn)行開(kāi)發(fā),然后通過(guò)提交pull request的方式提交自己的貢獻(xiàn)。
基礎(chǔ)依賴(lài)
因?yàn)樾枰Mfork的場(chǎng)景,所以準(zhǔn)備了2個(gè)github賬戶(hù):
一個(gè)是yang-ybb1(這個(gè)作為原開(kāi)發(fā)者)、一個(gè)是yang-ybb(這個(gè)作為自己)
操作過(guò)程
-
首先yang-ybb1(原作者)創(chuàng)建了一個(gè)項(xiàng)目,項(xiàng)目名為learn-git,項(xiàng)目默認(rèn)的分支是master分支,有一個(gè)默認(rèn)文件是README.md。此時(shí)原作者新建了一個(gè)開(kāi)發(fā)分支test_branch。到目前為止,原作者項(xiàng)目的結(jié)構(gòu)如下圖所示:
2個(gè)分支:master和test_branch
test_branch分支下只有一個(gè)README.md文件 此時(shí)yang-ybb(自己)fork了原作者的learn-git項(xiàng)目,此時(shí)在自己的github里面就有了learn-git項(xiàng)目,并且分支也是2個(gè)分支:master和test_branch,總體來(lái)說(shuō)就是和原作者操作1里面的代碼、分支都是一樣的。
-
原作者在他的分支test_branch上進(jìn)行了一些操作:新建了一個(gè)a.txt文件,文件內(nèi)容為“這個(gè)是a.txt文件”。此時(shí)原倉(cāng)庫(kù)的分支和文件如下:
在test_branch分支下面出現(xiàn)了一個(gè)a.txt文件
此時(shí)在看自己的倉(cāng)庫(kù)里面,分支還有文件都沒(méi)有變化,也就是說(shuō)原作者的改動(dòng)并沒(méi)有同步過(guò)來(lái)。
自己的倉(cāng)庫(kù)需要同步原作者改動(dòng)的部分。
# 首先把自己的倉(cāng)庫(kù)clone下來(lái)(*只需要執(zhí)行一次*)
> git clone git@github.com:yang-ybb/learn-git.git
# 進(jìn)入項(xiàng)目目錄
> cd learn-git
# 查看所有分支情況,可以看到目前本地分支只有master,遠(yuǎn)程的分支也只有自己的origin/master和origin/test_branchs
> git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/test_branch
# 查看遠(yuǎn)程信息,目前只有origin的信息,沒(méi)有原作者倉(cāng)庫(kù)的信息
> git remote -v
origin git@github.com:yang-ybb/learn-git.git (fetch)
origin git@github.com:yang-ybb/learn-git.git (push)
# 添加原作者倉(cāng)庫(kù)信息(注意這里的最后的鏈接是原作者git倉(cāng)庫(kù)的鏈接,yang-ybb1s)(*只需要執(zhí)行一次*)
> git remote add upstream git@github.com:yang-ybb1/learn-git.git
# 再查看一下遠(yuǎn)程信息,此時(shí)就發(fā)現(xiàn)多了upstream字段,也就是原作者倉(cāng)庫(kù)的地址
> git remote -v
origin git@github.com:yang-ybb/learn-git.git (fetch)
origin git@github.com:yang-ybb/learn-git.git (push)
upstream git@github.com:yang-ybb1/learn-git.git (fetch)
upstream git@github.com:yang-ybb1/learn-git.git (push)
# 如果發(fā)現(xiàn)upstream添加錯(cuò)誤了,使用git remote remove upstream刪除即可,然后再重新添加
# 拉取原作者倉(cāng)庫(kù)的代碼,可以看到拉取了upstream/master和upstream/test_branch
> git fetch upstream
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:yang-ybb1/learn-git
* [new branch] master -> upstream/master
* [new branch] test_branch -> upstream/test_branch
# 查看此時(shí)所有分支情況,新添加了2個(gè)upstream的分支
> git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/test_branch
remotes/upstream/master
remotes/upstream/test_branch
# 此時(shí)執(zhí)行下面2句就是相當(dāng)于把原作者倉(cāng)庫(kù)的master和本地master合并,然后提交到自己的倉(cāng)庫(kù)中。因?yàn)樵髡邆}(cāng)庫(kù)和自己的倉(cāng)庫(kù)master分支是一樣的,所以都是提示“Already up to date.”
> git merge upstream/master
Already up to date.
> git push
Everything up-to-date
# 現(xiàn)在要做的是拉取原作者倉(cāng)庫(kù)的test_branch分支的最新代碼,然后開(kāi)發(fā)后提交到自己的倉(cāng)庫(kù)中
# 首先肯定是要切換到test_branch倉(cāng)庫(kù)中。提示錯(cuò)誤:因?yàn)槭怯?個(gè)倉(cāng)庫(kù)都是叫test_branch,所以不知道是要切換到自己倉(cāng)庫(kù)的test_branch還是原作者倉(cāng)庫(kù)的test_branchs
> git checkout test_branch
error: pathspec 'test_branch' did not match any file(s) known to git
hint: 'test_branch' matched more than one remote tracking branch.
hint: We found 2 remotes with a reference that matched. So we fell back
hint: on trying to resolve the argument as a path, but failed there too!
hint:
hint: If you meant to check out a remote tracking branch on, e.g. 'origin',
hint: you can do so by fully qualifying the name with the --track option:
hint:
hint: git checkout --track origin/<name>
hint:
hint: If you d like to always have checkouts of an ambiguous <name> prefer
hint: one remote, e.g. the 'origin' remote, consider setting
hint: checkout.defaultRemote=origin in your config.
# 根據(jù)提示,切換到原作者倉(cāng)庫(kù)到test_branch。這樣就切換成功了。
> git checkout --track upstream/test_branch
Branch 'test_branch' set up to track remote branch 'test_branch' from 'upstream'.
Switched to a new branch 'test_branch'
# 注意這是切換到原作者倉(cāng)庫(kù)到test_branch分支,所以此時(shí)可以看到已經(jīng)有了a.txt文件,內(nèi)容也是一樣的
> ll
total 16
drwxr-xr-x 5 bytedance staff 160 8 24 21:13 ./
drwxr-xr-x+ 49 bytedance staff 1568 8 24 20:45 ../
drwxr-xr-x 14 bytedance staff 448 8 24 21:14 .git/
-rw-r--r-- 1 bytedance staff 11 8 24 20:45 README.md
-rw-r--r-- 1 bytedance staff 21 8 24 21:13 a.txt
# 然后自己改動(dòng)一些,比如在a.txt里添加新的一行,“自己添加了新的一行”
# 查看文件改動(dòng),注意這里的upstream/test_branch提醒是從原作者倉(cāng)庫(kù)拉取的代碼。
> git status
On branch test_branch
Your branch is up to date with 'upstream/test_branch'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: a.txt
no changes added to commit (use "git add" and/or "git commit -a")
> git add a.txt
> git commit -m "fork后的一次改動(dòng)提交"
[test_branch 6cace64] fork后的一次改動(dòng)提交
1 file changed, 1 insertion(+)
# 如果此時(shí)執(zhí)行g(shù)it push命令,后面不帶參數(shù),就會(huì)報(bào)錯(cuò),因?yàn)榇藭r(shí)push的默認(rèn)倉(cāng)庫(kù)是原作者倉(cāng)庫(kù),當(dāng)然沒(méi)有相應(yīng)的權(quán)限,就報(bào)錯(cuò)了~
> git push
ERROR: Permission to yang-ybb1/learn-git.git denied to yang-ybb.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
# 所以要正確的push到自己的倉(cāng)庫(kù)中。這樣就成功了。
> git push origin test_branch:test_branch
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 358 bytes | 358.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:yang-ybb/learn-git.git
5398efb..6cace64 test_branch -> test_branch

鞏固一下
- 還是先在原作者倉(cāng)庫(kù)里面修改,原作者在test_branch分支添加了一個(gè)b.txt文件,內(nèi)容是“這是一個(gè)b.txt文件”
- 回到自己的開(kāi)發(fā)當(dāng)中,還是進(jìn)入到項(xiàng)目文件中,查看當(dāng)前狀態(tài)和分支
# 由于自己之前在a.txt里面新添加了一行,所以提示領(lǐng)先upstream/test_branch分支,不用管,因?yàn)樽约阂矝](méi)有權(quán)限直接給原作者倉(cāng)庫(kù)提交更新。
> git status
On branch test_branch
Your branch is ahead of 'upstream/test_branch' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
# git pull = git fetch + git merge,這一步最容易發(fā)送沖突,如果沒(méi)有沖突就可以直接放下開(kāi)發(fā);如果有沖突需要先解決沖突。
> git pull
# 自己在a.txt里面新添加一行,“在a.txt里面添加的第三行,是第二次更新原作者倉(cāng)庫(kù)后進(jìn)行的開(kāi)發(fā)”
> git add a.txt
> git commit -m "第二次改動(dòng)提交"
> git push origin test_branch # 這里省略了最后的:test_branch,是因?yàn)槟J(rèn)提交的本地分支是當(dāng)前分支。
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 12 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 776 bytes | 776.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To github.com:yang-ybb/learn-git.git
6cace64..98b888b test_branch -> test_branch



