一碧注、電腦本地初始化一個(gè)倉(cāng)庫(kù)
1. git init: 初始化一個(gè)電腦上本地倉(cāng)庫(kù)
終端進(jìn)入項(xiàng)目目錄嚣伐,輸入:
$ git init
該命令將創(chuàng)建一個(gè)名為 .git 的子目錄,這個(gè)子目錄含有你初始化的 Git 倉(cāng)庫(kù)中所有的必須文件萍丐,這些文件是 Git 倉(cāng)庫(kù)的骨干轩端。
詳細(xì)介紹:https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-獲取-Git-倉(cāng)庫(kù)
2. 創(chuàng)建遠(yuǎn)程倉(cāng)庫(kù): 存放代碼
目前我知道的git網(wǎng)站倉(cāng)庫(kù):
碼云:
https://gitee.com/
公有倉(cāng)庫(kù)、私有倉(cāng)庫(kù)都免費(fèi)使用逝变, 國(guó)內(nèi)訪問(wèn)速度快基茵。
github:
https://github.com/
公有倉(cāng)庫(kù)免費(fèi)使用奋构, 私有倉(cāng)庫(kù)收費(fèi), 有時(shí)候訪問(wèn)速度慢拱层。
Bitbucket:
https://bitbucket.org/
公有倉(cāng)庫(kù)弥臼、私有倉(cāng)庫(kù)都免費(fèi)使用根灯, 但是免費(fèi)的最多只能有5個(gè)用戶對(duì)倉(cāng)庫(kù)進(jìn)行讀寫鼠锈,超過(guò)的就需要付費(fèi)邮丰。
訪問(wèn)速度有時(shí)很慢。
gitlab:
公司自建的git服務(wù)器丁存,隨意使用。
創(chuàng)建倉(cāng)庫(kù)都差不多,在網(wǎng)站中點(diǎn)擊新建倉(cāng)庫(kù)舌剂,然后選擇倉(cāng)庫(kù)的類型(公有、私有),然后點(diǎn)擊創(chuàng)建即可虏两。
3. 本地Git添加遠(yuǎn)程倉(cāng)庫(kù)地址
git remote add <shortname> <url>: 添加倉(cāng)庫(kù)
本地git初始化后定罢,此時(shí)還沒(méi)有添加遠(yuǎn)程倉(cāng)庫(kù)地址笤虫,需要添加一個(gè)遠(yuǎn)程倉(cāng)庫(kù)地址才能上傳代碼到服務(wù)器。
可在終端中運(yùn)行git remote add <shortname> <url>
添加一個(gè)新的遠(yuǎn)程 Git 倉(cāng)庫(kù)祖凫。
shortname
是url
的簡(jiǎn)寫琼蚯,當(dāng)上傳代碼的時(shí)候,可用這個(gè)簡(jiǎn)寫代替url
地址惠况。
命令詳細(xì)介紹:https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-遠(yuǎn)程倉(cāng)庫(kù)的使用
$ git remote add pb https://github.com/paulboone/ticgit
git remote -v
:查看本地git的遠(yuǎn)程倉(cāng)庫(kù)地址
當(dāng)添加好遠(yuǎn)程倉(cāng)庫(kù)后遭庶,可以使用命令來(lái)查看添加的倉(cāng)庫(kù)是否正確。
# 列出你指定的每一個(gè)遠(yuǎn)程服務(wù)器的簡(jiǎn)寫
$ git remote
origin
# 指定選項(xiàng) -v稠屠,會(huì)顯示需要讀寫遠(yuǎn)程倉(cāng)庫(kù)使用的 Git 保存的簡(jiǎn)寫與其對(duì)應(yīng)的 URL峦睡。
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
git remote show [remote-name] :查看遠(yuǎn)程倉(cāng)庫(kù)詳細(xì)信息
如果想要查看某一個(gè)遠(yuǎn)程倉(cāng)庫(kù)的更多信息,可以使用 git remote show [remote-name] 命令权埠。
如果想以一個(gè)特定的縮寫名運(yùn)行這個(gè)命令榨了,例如 origin,會(huì)得到像下面類似的信息:
$ git remote show origin
* remote origin
Fetch URL: https://github.com/schacon/ticgit
Push URL: https://github.com/schacon/ticgit
HEAD branch: master
Remote branches:
master tracked
dev-branch tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (up to date)
遠(yuǎn)程倉(cāng)庫(kù)的重命名弊知、移除阻逮、修改地址
如果想要重命名引用的名字可以運(yùn)行 git remote rename 去修改一個(gè)遠(yuǎn)程倉(cāng)庫(kù)的簡(jiǎn)寫名。
例如秩彤,想要將 pb 重命名為 paul,可以用 git remote rename 這樣做:
$ git remote rename pb paul
$ git remote
origin
paul
這同樣也會(huì)修改你的遠(yuǎn)程分支名字事哭。 那些過(guò)去引用 pb/master 的現(xiàn)在會(huì)引用 paul/master漫雷。
如果因?yàn)橐恍┰蛳胍瞥粋€(gè)遠(yuǎn)程倉(cāng)庫(kù) - 可以使用 git remote rm :
$ git remote rm paul
$ git remote
origin
修改地址:
git remote set-url origin www.baidu.com
關(guān)于遠(yuǎn)程倉(cāng)庫(kù)詳細(xì)介紹
二、從遠(yuǎn)程倉(cāng)庫(kù)(服務(wù)器)獲取代碼:本地什么也沒(méi)有鳍咱,拉取代碼
1. 獲取默認(rèn)分之代碼:git clone [URL]
如果本地沒(méi)有代碼降盹,遠(yuǎn)程倉(cāng)庫(kù)有代碼,則需要從遠(yuǎn)程倉(cāng)庫(kù)克隆代碼谤辜。
克隆倉(cāng)庫(kù)的命令格式是 git clone [url]
蓄坏。 比如价捧,要克隆 Git 的可鏈接庫(kù) libgit2,可以用下面的命令:
$ git clone https://github.com/libgit2/libgit2
這會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè)名為 “l(fā)ibgit2” 的目錄涡戳,并在這個(gè)目錄下初始化一個(gè) .git 文件夾结蟋,
從遠(yuǎn)程倉(cāng)庫(kù)拉取下所有數(shù)據(jù)放入 .git 文件夾,然后從中讀取最新版本的文件的拷貝渔彰。
如果你進(jìn)入到這個(gè)新建的 libgit2 文件夾嵌屎,你會(huì)發(fā)現(xiàn)所有的項(xiàng)目文件已經(jīng)在里面了,
準(zhǔn)備就緒等待后續(xù)的開(kāi)發(fā)和使用恍涂。
① 拉取倉(cāng)庫(kù)時(shí)自定義本地倉(cāng)庫(kù)文件名: git clone [URL] [新名字]
如果你想在克隆遠(yuǎn)程倉(cāng)庫(kù)的時(shí)候宝惰,自定義本地倉(cāng)庫(kù)的名字,你可以使用如下命令:
$ git clone https://github.com/libgit2/libgit2 mylibgit
這將執(zhí)行與上一個(gè)命令相同的操作再沧,不過(guò)在本地創(chuàng)建的倉(cāng)庫(kù)名字變?yōu)?mylibgit尼夺。
關(guān)于克隆遠(yuǎn)程倉(cāng)庫(kù)命令詳細(xì)介紹:https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-獲取-Git-倉(cāng)庫(kù)
2. 直接拉取特定分之的代碼:git clone -b [分支名] [代碼地址]
如果不想克隆默認(rèn)分之的代碼, 也可以克隆特定分之的代碼:
$ git clone http://192.168.102.9/jas-paas/cloudlink-front-framework.git
Cloning into 'cloudlink-front-framework'...
remote: Counting objects: 14436, done.
remote: Compressing objects: 100% (3072/3072), done.
remote: Total 14436 (delta 11224), reused 14226 (delta 11075)
Receiving objects: 100% (14436/14436), 17.93 MiB | 4.98 MiB/s, done.
Resolving deltas: 100% (11224/11224), done.
3. 直接拉取特定標(biāo)簽(tag)的代碼:git clone -b [標(biāo)簽名] [代碼地址]
git允許直接克隆特定分之的代碼炒瘸,不過(guò)克隆好后汞斧,項(xiàng)目里沒(méi)有分之,需要自己創(chuàng)建一個(gè)分支:
$ git clone -b V2.2 http://192.168.102.9/jas-paas/cloudlink-front-framework.git
Cloning into 'cloudlink-front-framework'...
remote: Counting objects: 14436, done.
remote: Compressing objects: 100% (3072/3072), done.
remote: Total 14436 (delta 11224), reused 14226 (delta 11075)
Receiving objects: 100% (14436/14436), 17.93 MiB | 4.70 MiB/s, done.
Resolving deltas: 100% (11224/11224), done.
Note: checking out 'eeea534cdae1f82c48c7b0de8f9993b54ffa065d'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
從信息中就可以看見(jiàn)什燕,克隆特定標(biāo)簽的項(xiàng)目后粘勒,是沒(méi)有分之的,需要進(jìn)入項(xiàng)目目錄后屎即,使用命令創(chuàng)建一個(gè)分支:
$ git checkout -b V2.2
4. 如果已經(jīng)拉取了代碼庙睡,還需要拉取其他分支代碼:git checkout -b [分支名] [遠(yuǎn)程倉(cāng)庫(kù)名]/[分支名]
例如,本地就一個(gè)master分支技俐,遠(yuǎn)程有2個(gè)分支(master,develop)乘陪,把遠(yuǎn)程的develop拉取到本地:
# 本地的分支是干凈的,也就是沒(méi)有修改的文件
# 獲取遠(yuǎn)程所有分支名字
~ git fetch
# 顯示遠(yuǎn)程所有分支名字
~ git branch -a
# 提取遠(yuǎn)程新分支到本地
~ git checkout -b develop origin/develop
三雕擂、記錄每次更新到倉(cāng)庫(kù)
1. GIT中文件狀態(tài)介紹(已跟蹤/未跟蹤)
工作目錄下每個(gè)文件只有兩種狀態(tài):
已跟蹤的兩種狀態(tài)
指那些被納入了版本控制的文件啡邑,在上一次快照中有它們的記錄,在工作一段時(shí)間后井赌,它們的狀態(tài)可能處于未修改谤逼,已修改或已放入暫存區(qū)。
初次克隆某個(gè)倉(cāng)庫(kù)的時(shí)候仇穗,工作目錄中的所有文件都屬于已跟蹤文件流部,并處于未修改狀態(tài)。
git會(huì)自動(dòng)管理已跟蹤
的文件纹坐,記錄文件處于什么狀態(tài)中枝冀。
已暫存(Changes to be committed)
文件在這個(gè)狀態(tài)下的,說(shuō)明已經(jīng)準(zhǔn)備好把文件提交了,可以把這次代碼變動(dòng)記錄保存在歷史記錄中果漾。
這個(gè)狀態(tài)為GIT可以提交的內(nèi)容球切。
已修改(Changes not staged for commit)
這狀態(tài)下的文件, git只是知道修改了那些內(nèi)容绒障,但是并不會(huì)在提交代碼的時(shí)候把這部分內(nèi)容提交上去吨凑。
如果需要提交這部分代碼需要使用命令git add
把文件添加到 已暫存中,然后提交代碼端盆。
未跟蹤(Untracked files)
工作目錄中除已跟蹤文件以外的所有其它文件都屬于未跟蹤文件怀骤,它們既不存在于上次快照的記錄中,也沒(méi)有放入暫存區(qū)焕妙。
git不會(huì)去管理這些文件寒砖。
2. git status
: 查看當(dāng)前文件狀態(tài)
使用git status
命令可以查看文件處于什么狀態(tài)缠劝,例如:
$ git status
On branch P02 // 告訴你當(dāng)前是哪個(gè)分之下
Your branch is up-to-date with 'origin/P02'. // 當(dāng)前分之是從哪個(gè)倉(cāng)庫(kù)更新的
Changes to be committed: // 已暫存狀態(tài)
(use "git reset HEAD <file>..." to unstage) // 使用這個(gè)命令可回退到Changes not staged for commit:
modified: fileName.ts
Changes not staged for commit: // 已跟蹤文件的內(nèi)容發(fā)生了變化
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: test.txt
Untracked files: // 未跟蹤的文件
(use "git add <file>..." to include in what will be committed)
src/library/
在git status
命令輸出的信息中:
Changes to be committed:
已暫存狀態(tài)
如果此時(shí)提交,那么該文件此時(shí)此刻的版本將被留存在歷史記錄中。
Changes not staged for commit:
已跟蹤文件的內(nèi)容發(fā)生了變化埠通,但還沒(méi)有放到暫存區(qū)埃疫。
Untracked files:
未跟蹤的文件帚湘,意味著 Git 在之前的快照(提交)中沒(méi)有這些文件哮针;
Git 不會(huì)自動(dòng)將之納入跟蹤范圍,除非你明明白白地告訴它“我需要跟蹤該文件”璧针,
這樣的處理讓你不必?fù)?dān)心將生成的二進(jìn)制文件或其它不想被跟蹤的文件包含進(jìn)來(lái)嚷炉。
3. git status -s
緊湊格式輸出
使用git status -s
命令或git status --short
命令,你將得到一種更為緊湊的格式輸出探橱。
$ git status -s
M README // 出現(xiàn)在右邊的 M 表示該文件被修改了但是還沒(méi)放入暫存區(qū)
MM Rakefile // 文件已經(jīng)放入暫存區(qū)申屹,但是又修改過(guò)了,在已修改中也存在
A lib/git.rb // 新添加到暫存區(qū)中的文件前面有 A 標(biāo)記
M lib/simplegit.rb // 出現(xiàn)在靠左邊的 M 表示該文件被修改了并放入了暫存區(qū)
?? LICENSE.txt // 新添加的未跟蹤文件前面有 ?? 標(biāo)記
4. GIT代碼管理:改變文件的狀態(tài)
git add
git add
命令是個(gè)多功能命令:可以用它開(kāi)始跟蹤新文件隧膏,或者把已跟蹤的文件放到暫存區(qū)哗讥,
還能用于合并時(shí)把有沖突的文件標(biāo)記為已解決狀態(tài)等。
將這個(gè)命令理解為“添加內(nèi)容到下一次提交中”而不是“將一個(gè)文件添加到項(xiàng)目中”要更加合適胞枕。
例子:
src/test.txt文件是一個(gè)未跟蹤文件杆煞,可使用git add
命令開(kāi)始跟蹤:
$ git add src/test.txt //指定單個(gè)文件添加
$ git add src/* //指定src目錄下所有文件都添加
git checkout -- <file>
: 撤消對(duì)文件的修改
如果你并不想保留對(duì) CONTRIBUTING.md 文件的修改,
將它還原成上次提交時(shí)的樣子(或者剛克隆完的樣子,或者剛把它放入工作目錄時(shí)的樣子)
可使用如下命令:
git checkout -- CONTRIBUTING.md
注:
你需要知道 git checkout -- [file] 是一個(gè)危險(xiǎn)的命令腐泻,這很重要决乎。
你對(duì)那個(gè)文件做的任何修改都會(huì)消失 - 你只是拷貝了另一個(gè)文件來(lái)覆蓋它。
除非你確實(shí)清楚不想要那個(gè)文件了贫悄,否則不要使用這個(gè)命令瑞驱。
git reset HEAD <file>
:取消暫存的文件
如果你在提交代碼的時(shí)候,不想提交一些文件窄坦,可使用該命令把文件從暫存中回退到已修改的文件中。
git reset HEAD CONTRIBUTING.md
關(guān)于撤銷操作的詳細(xì)介紹: https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-撤消操作
5. .gitignore:忽略文件,不納入GIT版本控制
一般我們總會(huì)有些文件無(wú)需納入 Git 的管理鸭津,也不希望它們總出現(xiàn)在未跟蹤文件列表彤侍。
通常都是些自動(dòng)生成的文件,比如日志文件逆趋,或者編譯過(guò)程中創(chuàng)建的臨時(shí)文件等盏阶。
在這種情況下,我們可以在項(xiàng)目根目錄創(chuàng)建一個(gè)名為 .gitignore 的文件闻书,列出要忽略的文件模式名斟。
文件 .gitignore 的格式規(guī)范如下:
- 所有空行或者以 # 開(kāi)頭的行都會(huì)被 Git 忽略。
- 可以使用標(biāo)準(zhǔn)的 glob 模式匹配魄眉。
- 匹配模式可以以(/)開(kāi)頭防止遞歸砰盐。
- 匹配模式可以以(/)結(jié)尾指定目錄。
- 要忽略指定模式以外的文件或目錄坑律,可以在模式前加上驚嘆號(hào)(!)取反岩梳。
一個(gè) .gitignore 文件的例子:
# 忽略所有后綴為 .a 的文件
*.a
# 但是要跟蹤lib.a,即使你上面忽略了 .a文件
!lib.a
# 僅忽略當(dāng)前目錄的TODO文件夾晃择, 不是subdir/TODO
/TODO
# 忽略build /目錄中的所有文件
build/
# 忽略doc / notes.txt冀值,而不是doc / server / arch.txt
doc/*.txt
# 忽略doc 目錄中的所有.pdf文件
doc/**/*.pdf
GitHub 有一個(gè)十分詳細(xì)的針對(duì)數(shù)十種項(xiàng)目及語(yǔ)言的 .gitignore 文件列表:
https://github.com/github/gitignore
這部分詳細(xì)介紹: https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-記錄每次更新到倉(cāng)庫(kù)
6. git diff: 查看代碼修改詳細(xì)內(nèi)容
如果你想知道文件具體修改了什么,可以用git diff
命令宫屠。
Ⅰ. git diff: 查看尚未暫存的文件修改記錄
git diff
命令查看修改之后還沒(méi)有暫存起來(lái)的變化內(nèi)容列疗。也就是git status
命令輸出信息中,
Changes not staged for commit:
下面的文件浪蹂, 例如:
$ git diff //查看所有詳細(xì)修改
$ git diff 1.txt //只查看 1.txt文件的 詳細(xì)修改
//輸出信息如下
diff --git a/.gitignore b/.gitignore //①
index e722882..f98470c 100644 //②
--- a/.gitignore //③
+++ b/.gitignore //③
@@ -3,8 +3,8 @@ //④
*~
*.sw[mnpcod]
-.DS_Store //⑤
*.log //⑥
+text.t //⑦
*.tmp
*.tmp.*
log.txt
① git格式的diff,進(jìn)行比較的是抵栈,a版本的.gitignore(即變動(dòng)前)和b版本的.gitignore(即變動(dòng)后)。
② 表示兩個(gè)版本的git哈希值(index區(qū)域的e722882對(duì)象乌逐,與工作目錄區(qū)域的f98470c對(duì)象進(jìn)行比較)竭讳,
最后的六位數(shù)字是對(duì)象的模式(普通文件,644權(quán)限)浙踢。
③ 表示進(jìn)行比較的兩個(gè)文件绢慢。 "---"表示變動(dòng)前的版本,"+++"表示變動(dòng)后的版本洛波。
④ 下面代碼所在的行:
-3,7: 修改前下面信息變化的行胰舆, 從第3行開(kāi)始一直到第7行
+3,6: 修改后下面信息變化的行, 從第3行開(kāi)始一直到第6行
⑤ 以-
開(kāi)頭表示刪除的代碼
⑥ 以空格開(kāi)頭表示沒(méi)有修改
⑦ 以+
開(kāi)頭便是增加的代碼
Ⅱ. git diff --staged: 查看以暫存文件修改記錄
查看已暫存的將要添加到下次提交里的內(nèi)容可是使用命令git diff --staged
(GIT版本1.6.1以上)蹬挤。
也可以使用git diff --cached
命令缚窿。
git diff --staged // 查看所有已暫存文件的修改記錄
git diff --staged t.txt // 只查看1.txt文件 已暫存的修改記錄
Ⅲ. git diff 的其他用法: --stat HEAD SHA1
~ git diff --stat // 查看簡(jiǎn)單的diff結(jié)果,只查看修改的文件名焰扳、修改了多少內(nèi)容
~ git diff HEAD // 查看所有修改記錄(已暫存倦零、已修改):顯示工作版本(Working tree)和HEAD的差別
~ git diff topic master // 直接將兩個(gè)分支上最新的提交做diff
~ git diff HEAD^ HEAD // 比較上次提交commit和上上次提交
~ git diff SHA1 SHA2 // 比較兩個(gè)歷史版本之間的差異
7. 把代碼納入版本控制中: 提交更新 git commit
當(dāng)所有需要提交的代碼都放到暫存區(qū)后误续,就可以提交代碼了:
$ git commit
這種方式會(huì)啟動(dòng)文本編輯器以便輸入本次提交的說(shuō)明。
一般都是 vim 或 emacs扫茅。使用 git config --global core.editor 命令設(shè)定你喜歡的編輯軟件蹋嵌。
編輯器會(huì)顯示類似下面的文本信息(本例選用 Vim 的屏顯方式展示):
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# new file: README
# modified: CONTRIBUTING.md
#
~
~
".git/COMMIT_EDITMSG" 9L, 283C
可以在這段文本信息中看見(jiàn), 所有以#
符號(hào)開(kāi)頭的行葫隙,都會(huì)被忽略栽烂,也就是#
是注釋行,不會(huì)放到提交信息中去恋脚。
接下來(lái)就可以輸入一些提交信息了腺办,關(guān)于寫提交信息的建議:
信息應(yīng)當(dāng)以少于 50 個(gè)字符(25個(gè)漢字)的單行開(kāi)始且簡(jiǎn)要地描述變更,接著是一個(gè)空白行糟描,再接著是一個(gè)更詳細(xì)的解釋怀喉。
Git 項(xiàng)目要求一個(gè)更詳細(xì)的解釋,包括做改動(dòng)的動(dòng)機(jī)和它的實(shí)現(xiàn)與之前行為的對(duì)比 - 這是一個(gè)值得遵循的好規(guī)則蚓挤。
提交信息簡(jiǎn)單的模板:
修改的摘要(50 個(gè)字符或更少)
如果必要的話磺送,加入更詳細(xì)的解釋文字。在
大概 72 個(gè)字符的時(shí)候換行灿意。在某些情形下估灿,
第一行被當(dāng)作一封電子郵件的標(biāo)題,剩下的
文本作為正文缤剧。分隔摘要與正文的空行是
必須的(除非你完全省略正文)馅袁;如果你將
兩者混在一起,那么類似變基等工具無(wú)法
正常工作荒辕。
關(guān)于VIM編輯器使用教程: vim編輯器常用命令與用法總結(jié)
commit命令的其他的用法: -m選項(xiàng)汗销,提交信息簡(jiǎn)寫
在 commit 命令后添加 -m 選項(xiàng),將提交信息與命令放在同一行抵窒,如下所示:
$ git ci -m "測(cè)試提交"
[master f949399] 測(cè)試提交
1 file changed, 1 insertion(+)
從輸出的信息中可以看見(jiàn):
當(dāng)前是在哪個(gè)分支(master)提交的弛针,本次提交的完整 SHA-1 校驗(yàn)和是什么(f949399),
以及在本次提交中李皇,有多少文件修訂過(guò)削茁,多少行添加和刪改過(guò)。
注意:
提交時(shí)記錄的是放在暫存區(qū)域的快照掉房。 任何還未暫存的仍然保持已修改狀態(tài)茧跋,可以在下次提交時(shí)納入版本管理。
每一次運(yùn)行提交操作卓囚,都是對(duì)你項(xiàng)目作一次快照瘾杭,以后可以回到這個(gè)狀態(tài),或者進(jìn)行比較哪亿。
commit命令的其他的用法: -a選項(xiàng),提交所有修改過(guò)的文件(已暫存粥烁,已修改)
有時(shí)候把修改的提交到暫存區(qū)贤笆,然后在提交代碼比較繁瑣, GIT提供了一種-a
選項(xiàng)页徐,在提交代碼的時(shí)候苏潜,
跳過(guò)暫存區(qū)银萍,把所有已經(jīng)跟蹤的文件暫存起來(lái)一并提交变勇,從而跳過(guò)git add
步驟,例如:
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: CONTRIBUTING.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
1 file changed, 5 insertions(+), 0 deletions(-)
從輸出信息中可以看到:提交之前不再需要 git add 文件“CONTRIBUTING.md”了贴唇。
關(guān)于git commit
命令詳解:https://git-scm.com/book/zh/v2/Git-基礎(chǔ)-記錄每次更新到倉(cāng)庫(kù)
8. git push: 把本地的跟新推送到遠(yuǎn)程倉(cāng)庫(kù)服務(wù)器上
當(dāng)在本地開(kāi)發(fā)完畢搀绣,需要把代碼提交到服務(wù)器時(shí),可使用it push [remote-name] [branch-name]
命令戳气。
你想要將 master 分支推送到 origin 服務(wù)器時(shí):
$ git push origin master // 把更新上傳到 origin服務(wù)器的 master分之上链患。
$ git push // 上傳本地所有分支代碼到遠(yuǎn)程對(duì)應(yīng)的分支上
只有當(dāng)你有所克隆服務(wù)器的寫入權(quán)限,并且之前沒(méi)有人推送過(guò)時(shí)瓶您,這條命令才能生效麻捻。
當(dāng)你和其他人在同一時(shí)間克隆,他們先推送到上游然后你再推送到上游呀袱,你的推送就會(huì)毫無(wú)疑問(wèn)地被拒絕贸毕。
你必須先將他們的工作拉取下來(lái)并將其合并進(jìn)你的工作后才能推送。
四夜赵、 查看提交歷史: git log
在提交了若干更新明棍,又或者克隆了某個(gè)項(xiàng)目之后,你也許想回顧下提交歷史寇僧。 完成這個(gè)任務(wù)最簡(jiǎn)單而又有效的工具是 git log 命令:
$ git log
commit ca82a6dff817ec66f44342007202690a93763949 // 提交的 SHA-1 校驗(yàn)和
Author: Scott Chacon <schacon@gee-mail.com> // 作者的名字和電子郵件地址
Date: Mon Mar 17 21:52:11 2008 -0700 // 提交時(shí)間
changed the version number // 提交說(shuō)明
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date: Sat Mar 15 16:40:33 2008 -0700
removed unnecessary test
默認(rèn)不用任何參數(shù)的話摊腋,git log 會(huì)按提交時(shí)間列出所有的更新,最近的更新排在最上面嘁傀。
git log 的常用選項(xiàng): -stat, -p, --name-status, --pretty=oneline, --abbrev-commit
git log --stat
:顯示每次更新的文件修改統(tǒng)計(jì)信息(修改的文件名兴蒸,每個(gè)文件添加的多少、刪除了多少數(shù)字)细办。
git log --name-only
: 只顯示修改的文件名橙凳,沒(méi)有其他信息
git log --pretty=oneline
: 用一行顯示信息
$ git log 1.txt //查看 1.txt文件的歷史修改記錄。
$ git log -n //只查看前n次修改記錄蟹腾,例如查看前2次的記錄: git log -2
$ git log -p // 按補(bǔ)丁格式顯示每個(gè)更新之間的差異痕惋。
$ git log --shortstat // 只顯示 --stat 中最后的行數(shù)修改添加移除統(tǒng)計(jì)。
$ git log --name-status // 顯示新增娃殖、修改值戳、刪除的文件清單。
$ git log --abbrev-commit // 僅顯示 SHA-1 的前幾個(gè)字符炉爆,而非所有的 40 個(gè)字符堕虹。
$ git log --relative-date // 使用較短的相對(duì)時(shí)間顯示(比如卧晓,“2 weeks ago”)。
$ git log --graph // 顯示 分支合并歷史赴捞。
$ git log --pretty=oneline // 用一行顯示信息
// 使用其他格式顯示歷史提交信息逼裆。可用的選項(xiàng)包括 oneline赦政,short胜宇,full,fuller 和 format(后跟指定格式)恢着。
五桐愉、 打標(biāo)簽(一個(gè)版本發(fā)布) git tag
像其他版本控制系統(tǒng)(VCS)一樣,Git 可以給歷史中的某一個(gè)提交打上標(biāo)簽掰派,以示重要从诲。
比較有代表性的是人們會(huì)使用這個(gè)功能來(lái)標(biāo)記發(fā)布版本節(jié)點(diǎn)(v1.0 等等)。
1. 什么是標(biāo)簽靡羡?
標(biāo)簽可以認(rèn)為是版本管理工具的一個(gè)版本系洛,也就是說(shuō)像很多第三方開(kāi)源軟件安裝包表示的版本號(hào),
比如說(shuō)1.0,2.0等等略步,它代表修復(fù)了一個(gè)bug,或者重大的重構(gòu)描扯,git的標(biāo)簽也是這樣的一個(gè)作用,
可以對(duì)版本的不同階段做一個(gè)標(biāo)示纳像。
2. 查看現(xiàn)有的標(biāo)簽
① 查看所有標(biāo)簽:git tag
$ git tag
v0.1
v1.3
v1.4
這個(gè)命令以字母順序列出標(biāo)簽荆烈;但是它們出現(xiàn)的順序并不重要帆竹。
② 查看符合條件的標(biāo)簽:git tag -l 'v1.*'
也可以使用特定的模式查找標(biāo)簽, 如果只對(duì) 1.0以上tag感興趣茅逮,可以運(yùn)行:
$ git tag -l 'v1.*'
③ 查看一個(gè)標(biāo)簽的詳細(xì)信息:git tag show V1.4
該命令會(huì)輸出打標(biāo)簽者的信息、打標(biāo)簽的日期時(shí)間德绿、附注信息岔帽,然后顯示具體的提交信息玫鸟。
3. 創(chuàng)建標(biāo)簽:Git 使用兩種主要類型的標(biāo)簽:
① git tag -a
:創(chuàng)建附注標(biāo)簽(annotated)
附注標(biāo)簽是存儲(chǔ)在 Git 數(shù)據(jù)庫(kù)中的一個(gè)完整對(duì)象。
它們是可以被校驗(yàn)的犀勒;其中包含打標(biāo)簽者的名字屎飘、電子郵件地址、日期時(shí)間贾费;還有一個(gè)標(biāo)簽信息钦购;
并且可以使用 GNU Privacy Guard (GPG)簽名與驗(yàn)證。 通常建議創(chuàng)建附注標(biāo)簽褂萧,這樣你可以擁有以上所有信息押桃。
創(chuàng)建一個(gè)附注標(biāo)簽,使用tag
命令時(shí)指定-a
選項(xiàng):
$ git tag -a v1.4 -m 'my version 1.4'
-m
選項(xiàng)指定了一條將會(huì)存儲(chǔ)在標(biāo)簽中的信息导犹。 如果沒(méi)有為附注標(biāo)簽指定一條信息唱凯,Git 會(huì)運(yùn)行編輯器要求你輸入信息羡忘。
如果你有自己的私鑰,還可以用 GPG 來(lái)簽署標(biāo)簽磕昼,只需要把之前的-a
改為-s
(取 signed 的首字母)即可:
git tag -s v1.5 -m 'my signed 1.5 tag'
再運(yùn)行 git show 會(huì)看到對(duì)應(yīng)的 GPG 簽名也附在其內(nèi).
② git tag V1.4
: 創(chuàng)建輕量標(biāo)簽(lightweight)
如果你只是想用一個(gè)臨時(shí)的標(biāo)簽卷雕,或者因?yàn)槟承┰虿幌胍4婺切┬畔ⅲ瑒t可以選擇使用輕量標(biāo)簽票从。
輕量標(biāo)簽本質(zhì)上是將提交校驗(yàn)和存儲(chǔ)到一個(gè)文件中 - 沒(méi)有保存任何其他信息漫雕。
創(chuàng)建輕量標(biāo)簽,不需要使用 -a纫骑、-s 或 -m 選項(xiàng)蝎亚,只需要提供標(biāo)簽名字:
$ git tag v1.4-lw
③ git tag -a v1.2 9fceb02
:對(duì)某個(gè)歷史提交打標(biāo)簽(后期打標(biāo)簽)
如果你在項(xiàng)目版本發(fā)布的時(shí)候忙忘記打標(biāo)簽,你可以在之后補(bǔ)上標(biāo)簽先馆。
要在那個(gè)提交上打標(biāo)簽,你需要在命令的末尾指定提交的校驗(yàn)和(或部分校驗(yàn)和):
git tag -a v1.2 9fceb02
4. 把創(chuàng)建的標(biāo)簽推送到服務(wù)器上:git push origin [tagname]
默認(rèn)情況下躺彬,git push
命令并不會(huì)傳送標(biāo)簽到遠(yuǎn)程倉(cāng)庫(kù)服務(wù)器上煤墙。 在創(chuàng)建完標(biāo)簽后你必須顯式地推送標(biāo)簽到共享服務(wù)器上。
$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag] v1.5 -> v1.5
如果想要一次性推送很多標(biāo)簽宪拥,也可以使用帶有--tags
選項(xiàng)的git push
命令仿野。
這將會(huì)把所有不在遠(yuǎn)程倉(cāng)庫(kù)服務(wù)器上的標(biāo)簽全部傳送到服務(wù)器。
$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag] v1.4 -> v1.4
* [new tag] v1.4-lw -> v1.4-lw
現(xiàn)在她君,當(dāng)其他人從倉(cāng)庫(kù)中克隆或拉取脚作,他們也能得到你的那些標(biāo)簽。
5. 檢出標(biāo)簽: 代碼變成標(biāo)簽的樣子
在 Git 中你并不能真的檢出一個(gè)標(biāo)簽缔刹,因?yàn)樗鼈儾⒉荒芟穹种б粯觼?lái)回移動(dòng)球涛。
如果你想要工作目錄與倉(cāng)庫(kù)中特定的標(biāo)簽版本完全一樣,
可以使用git checkout -b [branchname] [tagname]
在特定的標(biāo)簽上創(chuàng)建一個(gè)新分支:
$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'
6. 刪除標(biāo)簽
① git tag -d v1.0
:刪除本地標(biāo)簽
$ git tag -d v1.0
Deleted tag 'v1.0' (was 2ffea56)
② git push origin :refs/tags/v0.1
:刪除服務(wù)器標(biāo)簽
$ git push origin :refs/tags/v0.1
To http://192.168.95.95/user/test.git
- [deleted] v0.1
如果服務(wù)器的標(biāo)簽刪除后校镐,本地的也需要自己刪除亿扁。
六、 GIT分支
1. 分支介紹作用
Git 的分支鸟廓,其實(shí)本質(zhì)上僅僅是指向提交對(duì)象的可變指針从祝。 Git 的默認(rèn)分支名字是 master。
在多次提交操作之后引谜,你其實(shí)已經(jīng)有一個(gè)指向最后那個(gè)提交對(duì)象的 master 分支牍陌。 它會(huì)在每次的提交操作中自動(dòng)向前移動(dòng)。
分支作用:
- 開(kāi)發(fā)多個(gè)項(xiàng)目任務(wù)员咽,比如說(shuō)我有兩個(gè)任務(wù)都比較緊急毒涧,任務(wù)1需要兩天完成,任務(wù)2需要一天完成骏融,而任務(wù)1是之前就已經(jīng)開(kāi)始進(jìn)行的链嘀,任務(wù)二是中間加的新任務(wù)萌狂,所以需要第一天就完成任務(wù)2.
- master分支始終要保證可發(fā)布的狀態(tài),用dev分支和bug分支進(jìn)行開(kāi)發(fā)和錯(cuò)誤調(diào)試怀泊,這樣能夠保證主干代碼的干凈茫藏、可發(fā)布。
- 自己開(kāi)發(fā)測(cè)試或者修復(fù)BUG等等霹琼,可以避免代碼的丟失务傲。
2. 本地分支的創(chuàng)建、切換枣申、刪除:
① 創(chuàng)建分支:git branch testing
比如售葡,創(chuàng)建一個(gè) testing 分支, 你需要使用 git branch 命令:
$ git branch testing
這條命令會(huì)根據(jù)當(dāng)前的分支來(lái)創(chuàng)建一個(gè)新分支忠藤,分支中內(nèi)容與當(dāng)前分支內(nèi)容完全一樣挟伙。
git branch
命令僅僅 創(chuàng)建 一個(gè)新分支,并不會(huì)自動(dòng)切換到新分支中去模孩。
② 切換分支:git checkout testing
要切換到一個(gè)已存在的分支尖阔,你需要使用git checkout
命令。 我們現(xiàn)在切換到新創(chuàng)建的 testing 分支去:
$ git checkout testing
③ 創(chuàng)建并且換:git checkout -b testing
$ git checkout -b testing
Switched to a new branch "testing"
這個(gè)命令會(huì)創(chuàng)建一個(gè)分支并切換到新分支中去榨咐, 實(shí)際上他是上面2條命令的簡(jiǎn)化版介却。
④ 刪除分支:git branch -d testing
刪除一個(gè)分支的時(shí)候,你不能在要?jiǎng)h除的分支中块茁,要切換到別的分支中齿坷,否則會(huì)報(bào)錯(cuò)。
如果要?jiǎng)h除 testing分支数焊,可以使用帶 -d 選項(xiàng)的 git branch 命令來(lái)刪除分支:
$ git br -d testing
Deleted branch testing (was 4baf2a3).
3. 遠(yuǎn)程倉(cāng)庫(kù)分支的新建與刪除
①遠(yuǎn)程倉(cāng)庫(kù)分支的新建: git push origin testing
如果想把本地的新分支推送到遠(yuǎn)程倉(cāng)庫(kù)永淌,可使用 git push [遠(yuǎn)程倉(cāng)庫(kù)名] [分支名]
:
$ git br -a
testing
* master
remotes/origin/master
$ git push origin testing
Total 0 (delta 0), reused 0 (delta 0)
To http://192.168.132.55/user/test.git
* [new branch] testing -> testing
② 刪除遠(yuǎn)程倉(cāng)庫(kù)的無(wú)用分支:git push origin --delete testing
如果遠(yuǎn)程倉(cāng)庫(kù)某個(gè)分支無(wú)用了,想要?jiǎng)h除昌跌,可以運(yùn)行帶有 --delete 選項(xiàng)的 git push 命令來(lái)刪除一個(gè)遠(yuǎn)程分支:
git push origin --delete testing
To http://192.168.132.55/user/test.git
- [deleted] testing
4. 分支合并:git merge
如果一個(gè)分支的功能開(kāi)發(fā)完畢了仰禀,需要把開(kāi)發(fā)的內(nèi)容合并的其他分支中去,則需要使用 git的 merge命令蚕愤。
例如答恶, 現(xiàn)在有2個(gè)分支(master, ningning), master分支的代碼要合并到ningning,2個(gè)分支代碼都已經(jīng)git commit過(guò)了。
如果沒(méi)有commit萍诱,需要先commit悬嗓,否則不能合并代碼。
① 合并命令:git merge [分支名]
// 切換到需要添加新功能的分支上
$ git checkout ningning
// 把 master分支上的代碼合并到ningning分支上
$ git merge master
② 合并很完美裕坊,直接合并成功的提示
如果合并成功了則輸出的信息類似于下面:
$ git merge master
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
// 或者下面的輸出信息
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Git 將合并的結(jié)果做了一個(gè)新的快照并且自動(dòng)創(chuàng)建一個(gè)新的提交指向它包竹。
③ 合并過(guò)程中代碼有沖突,解決沖突
錯(cuò)誤信息類似于:
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Auto-merging是指已經(jīng)自動(dòng)合并的文件,
CONFLICT (content)是指有沖突的文件周瞎,需要解決沖突的文件苗缩。
打開(kāi)有沖突的文件,沖突部分代碼類似于下面:
<<<<<<< HEAD:ningning
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> master
<<<<< ======= 中的是 ningning分支的代碼声诸。
======= >>>>>> 中的是 master分支的代碼酱讶。
經(jīng)過(guò)對(duì)比后刪除沖突部分的代碼, 并把 <<< ==== >>>> 所在行全部刪除彼乌。
保存后泻肯,使用git add
添加修改的文件。
使用git commit
命令來(lái)完成合并提交:
解決沖突文件:git checkout --ours/--theirs
放棄其中一個(gè)分支的沖突代碼
如果想放棄一個(gè)分支文件的沖突代碼慰照,只保留一個(gè)分支的代碼灶挟,可使用如下命令。
假如:沖突文件名為 1.txt毒租,要放棄master
分支的修改稚铣,可使用如下命令:
$ git checkout --ours 1.txt
放棄ningning
分支沖突代碼,可使用如下命令:
$ git checkout --theirs 1.txt
④ 取消合并
沖突太多蝌衔,解決沖突亂了榛泛, 可取消合并:git reset --hard HEAD
如果沖突代碼太多了,解決沖突代碼過(guò)程中產(chǎn)生了混亂噩斟,想要重新合并孤个,可使用下面命令取消這次合并:
git reset --hard HEAD
HEAD is now at 9e791f3 提交信息
合并已經(jīng)commit剃允,還沒(méi)上傳遠(yuǎn)程倉(cāng)庫(kù)牡肉,取消合并:git reset --hard HEAD^
如果合并的代碼產(chǎn)生了錯(cuò)誤饲窿,或者合并有問(wèn)題,但是已經(jīng)commit了焕蹄,但是還沒(méi)有把合并提交到遠(yuǎn)程倉(cāng)庫(kù)逾雄,則可以使用如下命令取消這次合并:
$ git reset --hard HEAD^
GIT的高級(jí)用法(平時(shí)用的很少,了解就好)
GIT工具: 儲(chǔ)藏與清理
1. git stash
: 修改的代碼暫存起來(lái),把工作目錄變干凈鸦泳,方便切換分支等做一些其他事情
當(dāng)你的工作已經(jīng)做了一段時(shí)間后银锻,所開(kāi)發(fā)的功能還沒(méi)有完成, 而這時(shí)候你想要切換分支做一點(diǎn)別的事情做鹰。
但你又不想應(yīng)為過(guò)一會(huì)就回到這一點(diǎn)而為做了一半工作就創(chuàng)建一次提交击纬,這個(gè)時(shí)候你就可以使用git stash
命令。
git stash
命令會(huì)處理工作目錄的臟的狀態(tài)誊垢,即修改的跟蹤文件與暫存的改動(dòng)掉弛。然后將未完成的修改保存到一個(gè)棧上,
而你可以在任何時(shí)候重新應(yīng)用這些改動(dòng)喂走。
① 把代碼儲(chǔ)藏起來(lái): git stash
$ git status
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
//儲(chǔ)藏代碼
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 added the index file"
HEAD is now at 049d078 added the index file
(To restore them type "git stash apply")
$ git status
# On branch master
nothing to commit, working directory clean
上面使用了git stash
儲(chǔ)藏了代碼殃饿,這時(shí)候在看工作目錄就變成干凈了,這個(gè)時(shí)候你就可以做別的事情了芋肠。
還可以使用git stash save
命令乎芳,與 git stash
是一樣的。
② 查看儲(chǔ)藏的代碼: git stash list
要查看儲(chǔ)藏的東西帖池,可以使用git stash list
命令:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
最新的是stash@{0}
③ 把儲(chǔ)藏的代碼取出來(lái): git stash apply
如果想把儲(chǔ)藏的代碼應(yīng)用回來(lái)奈惑,可使用git stash apply
命令,如果不指定一個(gè)儲(chǔ)藏睡汹,Git 認(rèn)為指定的是最近的儲(chǔ)藏肴甸。
如果想要應(yīng)用其中一個(gè)更舊的儲(chǔ)藏,可以通過(guò)名字指定它囚巴,像這樣:git stash apply stash@{2}
原在。
$ git stash apply --index
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: index.html
# modified: lib/simplegit.rb
#
git stash apply --index
文件的改動(dòng)被重新應(yīng)用了,但是之前已修改未暫存的文件卻沒(méi)有回到原來(lái)的位置,想要完全回到之前的樣子彤叉,
必須使用--index
選項(xiàng)來(lái)運(yùn)行git stash apply
命令庶柿,來(lái)嘗試重新應(yīng)用暫存的修改。
如果已經(jīng)那樣做了秽浇,那么你將回到原來(lái)的位置:
$ git stash apply --index
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: lib/simplegit.rb
#
④ 刪除儲(chǔ)藏堆棧上的某個(gè)儲(chǔ)藏:git stash drop stash@{0}
使用git stash apply
命令只會(huì)嘗試應(yīng)用暫存的工作 浮庐,在堆棧上還有它。
可以運(yùn)行git stash drop
加上將要移除的儲(chǔ)藏的名字來(lái)移除它:
$ git stash list
stash@{0}: WIP on master: 049d078 added the index file
stash@{1}: WIP on master: c264051 Revert "added file_size"
stash@{2}: WIP on master: 21d80a5 added number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
⑤ 應(yīng)用儲(chǔ)藏然后立即從棧上扔掉它:git stash pop
這個(gè)命令只會(huì)應(yīng)用最新的柬焕,然后丟掉它审残。
git stash --keep-index
: 不要儲(chǔ)藏任何你通過(guò) git add 命令已暫存的東西
當(dāng)你做了幾個(gè)改動(dòng)并只想提交其中的一部分,過(guò)一會(huì)兒再回來(lái)處理剩余改動(dòng)時(shí)击喂,這個(gè)功能會(huì)很有用维苔。
$ git status -s
M index.html
M lib/simplegit.rb
$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
M index.html
git stash -u
: 把任何創(chuàng)建的未跟蹤文件也儲(chǔ)藏
默認(rèn)情況下,git stash
只會(huì)儲(chǔ)藏已經(jīng)在索引中的文件懂昂。
如果指定 --include-untracked
或-u
標(biāo)記介时,Git 也會(huì)儲(chǔ)藏任何創(chuàng)建的未跟蹤文件。
$ git status -s
M index.html
M lib/simplegit.rb
?? new-file.txt
$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
$
從儲(chǔ)藏創(chuàng)建一個(gè)分支:解決應(yīng)用儲(chǔ)藏沖突問(wèn)題
如果儲(chǔ)藏了一些工作,將它留在那兒了一會(huì)兒沸柔,然后繼續(xù)在儲(chǔ)藏的分支上工作循衰,在重新應(yīng)用工作時(shí)可能會(huì)有問(wèn)題。
如果應(yīng)用嘗試修改剛剛修改的文件褐澎,你會(huì)得到一個(gè)合并沖突并不得不解決它会钝。
如果想要一個(gè)輕松的方式來(lái)再次測(cè)試儲(chǔ)藏的改動(dòng),可以運(yùn)行git stash branch
創(chuàng)建一個(gè)新分支工三,
檢出儲(chǔ)藏工作時(shí)所在的提交迁酸,重新在那應(yīng)用工作,然后在應(yīng)用成功后扔掉儲(chǔ)藏:
$ git stash branch testchanges
Switched to a new branch "testchanges"
# On branch testchanges
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: index.html
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
#
# modified: lib/simplegit.rb
#
Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
清理工作目錄
有時(shí)候你想清除工作目錄一些無(wú)用的文件俭正,或是為了運(yùn)行一個(gè)干凈的構(gòu)建而移除之前構(gòu)建的殘留奸鬓。
這個(gè)時(shí)候你可以使用git clean
命令。 它被設(shè)計(jì)為從工作目錄中移除未被追蹤的文件掸读。
如果你改變主意了串远,你也不一定能找回來(lái)那些文件的內(nèi)容。
一個(gè)更安全的選項(xiàng)是運(yùn)行 git stash --all 來(lái)移除每一樣?xùn)|西并存放在棧中儿惫。
git clean -f -d
:移除工作目錄中所有未追蹤的文件以及空的子目錄
-d
是 目錄的意思澡罚。
-f
意味著 強(qiáng)制 或 “確定移除”。
$ git clean -f -d
Removing 5.txt
Removing tttt/
git clean -f -d -n
: 做一次演習(xí)然后告訴你 將要 移除什么
git clean -f -d -x
: 移除.gitiignore文件中忽略的文件
默認(rèn)情況下肾请,git clean 命令只會(huì)移除沒(méi)有忽略的未跟蹤文件留搔。
任何與 .gitiignore 或其他忽略文件中的模式匹配的文件都不會(huì)被移除晕换。
如果你也想要移除那些文件矫限,例如為了做一次完全干凈的構(gòu)建而移除所有由構(gòu)建生成的 .o 文件,
可以給 clean 命令增加一個(gè) -x 選項(xiàng)呜舒。
$ git status -s
M lib/simplegit.rb
?? build.TMP
?? tmp/
$ git clean -n -d
Would remove build.TMP
Would remove tmp/
$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/
重寫歷史:git 提交歷史修改
1. 修改最后一次提交
修改你最近一次提交可能是所有修改歷史提交的操作中最常見(jiàn)的一個(gè)避归。
對(duì)于你的最近一次提交,你往往想做兩件事情:修改提交信息管呵,或者修改你添加梳毙、修改和移除的文件的快照。
① 只是修改最后一次提交的提交信息:git commit --amend
如果只是想修改最后一次提交的提交信息捐下,可以直接使用如下命令:
$ git commit --amend
[dev 3fa2e1a] 合并提交測(cè)試3號(hào),測(cè)試修改最后一次提交账锹。在測(cè)試一下。
Date: Thu Nov 2 11:29:00 2017 +0800
1 file changed, 1 insertion(+)
create mode 100644 5.txt
這會(huì)把你帶入文本編輯器坷襟,里面包含了你最近一條提交信息奸柬,供你修改。
當(dāng)保存并關(guān)閉編輯器后婴程,編輯器將會(huì)用你輸入的內(nèi)容替換最近一條提交信息廓奕。
② 修改最后一次提交的快照:git add
或git rm
然后git commit --amend
如果你已經(jīng)完成提交,又因?yàn)橹疤峤粫r(shí)忘記添加一個(gè)新創(chuàng)建的文件,想通過(guò)添加或修改文件來(lái)更改提交的快照桌粉,
也可以通過(guò)類似的操作來(lái)完成蒸绩。 通過(guò)修改文件然后運(yùn)行git add
或git rm
一個(gè)已追蹤的文件,
隨后運(yùn)行git commit --amend
拿走當(dāng)前的暫存區(qū)域并使其做為新提交的快照铃肯。
使用這個(gè)技巧的時(shí)候需要小心患亿,因?yàn)樾拚龝?huì)改變提交的 SHA-1 校驗(yàn)和。
它類似于一個(gè)小的變基 - 如果已經(jīng)推送了最后一次提交則需要慎重修改押逼。
③ 把修改的最后一次提交信息強(qiáng)推到服務(wù)器:git push --f
此操作要慎重步藕,如果要修改服務(wù)器上的最后一次提交,可現(xiàn)在本地修改挑格,
然后使用git push --f
(force)強(qiáng)推到服務(wù)器中去咙冗。
git push --force
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 458 bytes | 458.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://192.168.102.9/yulilong/test.git
+ 5c0a032...3fa2e1a dev -> dev (forced update)
④ gitlab服務(wù)器強(qiáng)推被拒絕: 倉(cāng)庫(kù) -> 設(shè)置 -> 保護(hù)分支: 把被保護(hù)的分支去掉即可解決問(wèn)題
2. 使用git rebase合并多次commit
使用git log
查看一下歷史:
$ git log
commit 3fa2e1a951ff823fbec625a96049e27ef35a85b8 (HEAD -> dev, origin/dev)
Author: yulilong <yulilong222q@outlook.com>
Date: Thu Nov 2 11:29:00 2017 +0800
合并提交測(cè)試3號(hào),測(cè)試修改最后一次提交。在測(cè)試一下恕齐。
commit f526876def0b80676bfcf52937f78052e2d63955
Author: yulilong <yulilong222q@outlook.com>
Date: Thu Nov 2 11:27:20 2017 +0800
合并提交測(cè)試2號(hào)
commit 4d2b6ce4d5154c0b739e552e679bb7f4ce05fb2c
Author: yulilong <yulilong222q@outlook.com>
Date: Thu Nov 2 11:25:59 2017 +0800
合并提交測(cè)試一號(hào)
commit 9e791f38f4d5f472a371a8c147f37670185582f8
Author: yulilong <yulilong222q@outlook.com>
Date: Mon Oct 30 10:22:02 2017 +0800
這是dev分支上的合并提交測(cè)試
commit 4baf2a319c0de8f46630ba85db11cc4aebd1d2cd
Author: yulilong <yulilong222q@outlook.com>
Date: Fri Sep 29 10:20:08 2017 +0800
這是測(cè)試-a -m命令提交記錄
如果想要合并最后三次的提交乞娄,可使用git rebase -i HEAD~3
或git rebase -i 9e791f38f4d
命令來(lái)壓縮.
該命令執(zhí)行后,會(huì)彈出一個(gè)編輯窗口显歧,3次提交的commit倒序排列仪或,最上面的是最早的提交,最下面的是最近一次提交士骤。
1 pick 4d2b6ce 合并提交測(cè)試一號(hào)
2 pick f526876 合并提交測(cè)試2號(hào)
3 pick 3fa2e1a 合并提交測(cè)試3號(hào),測(cè)試修改最后一次提交范删。在測(cè)試一下。
4
5 # Rebase 9e791f3..3fa2e1a onto 9e791f3 (3 commands)
6 #
7 # Commands:
8 # p, pick = use commit
9 # r, reword = use commit, but edit the commit message
10 # e, edit = use commit, but stop for amending
11 # s, squash = use commit, but meld into previous commit
12 # f, fixup = like "squash", but discard this commit's log message
13 # x, exec = run command (the rest of the line) using shell
14 # d, drop = remove commit
15 #
16 # These lines can be re-ordered; they are executed from top to bottom.
17 #
18 # If you remove a line here THAT COMMIT WILL BE LOST.
19 #
20 # However, if you remove everything, the rebase will be aborted.
21 #
22 # Note that empty commits are commented out
修改第二行拷肌、第三行的第一個(gè)單詞pick為squash(這些命令什么意思下面的注釋有說(shuō)明)到旦。
然后保存退出,git會(huì)壓縮提交歷史巨缘,
如果有沖突添忘,需要修改,修改的時(shí)候要注意若锁,保留最新的歷史搁骑,不然我們的修改就丟棄了。
修改以后要記得敲下面的命令:
$ git add .
# git rebase --continue
如果你想放棄這次壓縮的話又固,執(zhí)行以下命令:
$ git rebase --abort
如果沒(méi)有沖突仲器,或者沖突已經(jīng)解決,則會(huì)出現(xiàn)如下的編輯窗口:
1 # This is a combination of 3 commits.
2 # This is the 1st commit message:
3
4 合并提交測(cè)試一號(hào)
5
6 # This is the commit message #2:
7
8 合并提交測(cè)試2號(hào)
9
10 # This is the commit message #3:
11
12 合并提交測(cè)試3號(hào),測(cè)試修改最后一次提交仰冠。在測(cè)試一下乏冀。
13
14 # Please enter the commit message for your changes. Lines starting
15 # with '#' will be ignored, and an empty message aborts the commit.
16 #
17 # Date: Thu Nov 2 11:25:59 2017 +0800
18 #
19 # interactive rebase in progress; onto 9e791f3
20 # Last commands done (3 commands done):
21 # squash f526876 合并提交測(cè)試2號(hào)
22 # squash 3fa2e1a 合并提交測(cè)試3號(hào),測(cè)試修改最后一次提交。在測(cè)試一下洋只。
23 # No commands remaining.
24 # You are currently rebasing branch 'dev' on '9e791f3'.
25 #
26 # Changes to be committed:
27 # modified: 1.txt
28 # new file: 4.txt
29 # new file: 5.txt
編輯好合并的提交信息后保存辆沦,可看見(jiàn)如下輸出信息:
[detached HEAD 83d65c7] 三次合并提交的測(cè)試昼捍,成功了。
Date: Thu Nov 2 11:25:59 2017 +0800
3 files changed, 7 insertions(+)
create mode 100644 4.txt
create mode 100644 5.txt
Successfully rebased and updated refs/heads/dev.
最后把合并的記錄強(qiáng)推到服務(wù)器中去:
git push -f
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 596 bytes | 596.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0)
To http://192.168.102.9/yulilong/test.git
+ 3fa2e1a...83d65c7 dev -> dev (forced update)
服務(wù)器合并提交前:
服務(wù)器合并后:
參考鏈接:http://blog.csdn.net/yangcs2009/article/details/47166361
3. 把一個(gè)文件從提交歷史中徹底刪除:git filter-branch --tree-filter 'rm -f 1.txt' HEAD
有些人不經(jīng)思考使用git add .众辨,意外地提交了一個(gè)巨大的二進(jìn)制文件端三,你想將它從所有地方刪除。
也許你不小心提交了一個(gè)包含密碼的文件鹃彻,而你想讓你的項(xiàng)目開(kāi)源郊闯。filter-branch大概會(huì)是你用來(lái)清理整個(gè)歷史的工具。
如果想要從整個(gè)歷史總刪除1.txt文件蛛株,你可以在filter-branch
上使用--tree-filte
r選項(xiàng):
$ git filter-branch -f --tree-filter 'rm -f 1.txt' HEAD
Rewrite 83d65c7b098e0ec1f14d9a332187632b49d2ad9f (5/5) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/dev' was rewritten
如果執(zhí)行命令的時(shí)候提示如下錯(cuò)誤团赁,刪除 .git/refs/original/ 目錄,或使用-f
命令強(qiáng)制覆蓋:
$ git filter-branch -f --tree-filter 'rm -f 1.txt' HEAD
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f
git filter-branch -f --tree-filter 'rm -f 1.txt' HEAD
Rewrite 83d65c7b098e0ec1f14d9a332187632b49d2ad9f (5/5) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/dev' was rewritten
如果后悔刪除了,可使用如下命令恢復(fù):git reset --hard refs/original/refs/heads/[分支名]
$ git reset --hard refs/original/refs/heads/dev
HEAD is now at 83d65c7 三次合并提交的測(cè)試谨履,成功了欢摄。
把刪除后的項(xiàng)目提交到服務(wù)器:git push origin +[分支名]
, 注意:一旦運(yùn)行此命令,刪除的文件不能找回
$ git push origin +dev
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (14/14), 1.40 KiB | 1.40 MiB/s, done.
Total 14 (delta 1), reused 0 (delta 0)
To http://192.168.102.110/user/test.git
+ 83d65c7...4b4da80 dev -> dev (forced update)
注意笋粟,分支名字前面的+
號(hào)一定不能忘記怀挠,否則會(huì)報(bào)如下錯(cuò)誤:
To http://192.168.102.110/user/test.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to 'http://192.168.102.110/user/test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
推送之前要把服務(wù)器的分支保護(hù)去掉,否則會(huì)報(bào)如下錯(cuò)誤:
remote: GitLab: You are not allowed to force push code to a protected branch on this project.
To http://192.168.102.110/user/test.git
! [remote rejected] dev -> dev (pre-receive hook declined)
error: failed to push some refs to 'http://192.168.102.110/user/test.git'
刪除一堆類似文件:git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD
全局性地更換電子郵件地址
$ git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="schacon@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
參考鏈接: https://git-scm.com/book/zh/v2/Git-工具-重寫歷史
GIT的工作原理
Git 的思維框架(將其作為內(nèi)容管理器)是管理三棵不同的樹(shù)害捕÷塘埽“樹(shù)” 在我們這里的實(shí)際意思是 “文件的集合”,而不是指特定的數(shù)據(jù)結(jié)構(gòu)尝盼。
Git 作為一個(gè)系統(tǒng)吞滞,是以它的一般操作來(lái)管理并操縱這三棵樹(shù)的:
----------------------------
樹(shù) 用途
HEAD 上一次提交的快照,下一次提交的父節(jié)點(diǎn)
index 預(yù)期的下一次提交的快照
Working Directory 沙盒(工作目錄)
- HEAD
HEAD 是當(dāng)前分支引用的指針盾沫,它總是指向該分支上的最后一次提交裁赠。 這表示 HEAD 將是下一次提交的父結(jié)點(diǎn)。
通常赴精,理解 HEAD 的最簡(jiǎn)方式佩捞,就是將它看做 你的上一次提交 的快照。
下例命令就顯示了HEAD
快照實(shí)際的目錄列表蕾哟,以及其中每個(gè)文件的SHA-1
校驗(yàn)和:
$ git cat-file -p HEAD
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
author Scott Chacon 1301511835 -0700
committer Scott Chacon 1301511835 -0700
initial commit
$ git ls-tree -r HEAD
100644 blob a906cb2a4a904a152... README
100644 blob 8f94139338f9404f2... Rakefile
040000 tree 99f1a6d12cb4b6f19... lib
cat-file
與ls-tree
是底層命令失尖,它們一般用于底層工作,在日常工作中并不使用渐苏。不過(guò)它們能幫助我們了解到底發(fā)生了什么。
- index
index(索引)是你的預(yù)期的下一次提交菇夸。也會(huì)將這個(gè)概念引用為 Git 的 “暫存區(qū)域”琼富,這就是當(dāng)你運(yùn)行git commit
時(shí)Git看起來(lái)的樣子。
Git 將上一次檢出到工作目錄中的所有文件填充到索引區(qū)庄新,它們看起來(lái)就像最初被檢出時(shí)的樣子鞠眉。
之后你會(huì)將其中一些文件替換為新版本薯鼠,接著通過(guò) git commit 將它們轉(zhuǎn)換為樹(shù)來(lái)用作新的提交。
$ git ls-files -s
100644 a906cb2a4a904a152e80877d4088654daad0c859 0 README
100644 8f94139338f9404f26296befa88755fc2598c289 0 Rakefile
100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0 lib/simplegit.rb
ls-files
是底層命令械蹋,它會(huì)顯示出索引當(dāng)前的樣子出皇。
確切來(lái)說(shuō),索引并非技術(shù)上的樹(shù)結(jié)構(gòu)哗戈,它其實(shí)是以扁平的清單實(shí)現(xiàn)的郊艘。不過(guò)對(duì)我們而言,把它當(dāng)做樹(shù)就夠了唯咬。
- Working Directory
Working Directory(工作目錄)纱注,最后,你就有了自己的工作目錄胆胰。
另外兩棵樹(shù)以一種高效但并不直觀的方式狞贱,將它們的內(nèi)容存儲(chǔ)在 .git 文件夾中。
工作目錄會(huì)將它們解包為實(shí)際的文件以便編輯蜀涨。 你可以把工作目錄當(dāng)做 沙盒瞎嬉。
在你將修改提交到暫存區(qū)并記錄到歷史之前,可以隨意更改厚柳。
工作流程
+-------------------------------------------------------------------+
| +--------------+ +---------------+ +--------------+ |
| | Working | | Index | | HEAD | |
| | Directory | | | | | |
| +-----+--------+ +-------+-------+ +-------+------+ |
| | | | |
| | | Checkout the project | |
| | <-------------------------------------------+ |
| | | | |
| | Stage Files | | |
| +---------------------> | | |
| | | Commit | |
| | +--------------------> | |
| | | | |
+-------------------------------------------------------------------+
假設(shè)我們進(jìn)入到一個(gè)新目錄氧枣,其中有一個(gè)文件。 我們稱其為該文件的 v1 版本草娜,將它標(biāo)記為藍(lán)色挑胸。
現(xiàn)在運(yùn)行git init
,這會(huì)創(chuàng)建一個(gè) Git 倉(cāng)庫(kù)宰闰,其中的 HEAD 引用指向未創(chuàng)建的分支(master 還不存在)茬贵。此時(shí),只有工作目錄有內(nèi)容移袍。 現(xiàn)在我們想要提交這個(gè)文件解藻,所以用
git add
來(lái)獲取工作目錄中的內(nèi)容,并將其復(fù)制到索引(Index)中葡盗。接著運(yùn)行
git commit
螟左,它首先會(huì)移除索引中的內(nèi)容并將它保存為一個(gè)永久的快照,
然后創(chuàng)建一個(gè)指向該快照的提交對(duì)象觅够,最后更新 master 來(lái)指向本次提交胶背。此時(shí)如果我們運(yùn)行
git status
,會(huì)發(fā)現(xiàn)沒(méi)有任何改動(dòng)喘先,因?yàn)楝F(xiàn)在三棵樹(shù)完全相同钳吟。
現(xiàn)在我們想要對(duì)文件進(jìn)行修改然后提交它。 我們將會(huì)經(jīng)歷同樣的過(guò)程窘拯;首先在工作目錄中修改文件红且。
我們稱其為該文件的 v2 版本坝茎,并將它標(biāo)記為紅色。如果現(xiàn)在運(yùn)行 git status暇番,我們會(huì)看到文件顯示在 “Changes not staged for commit,” 下面并被標(biāo)記為紅色嗤放,
因?yàn)樵摋l目在索引與工作目錄之間存在不同。 接著我們運(yùn)行git add
來(lái)將它暫存到索引中壁酬。此時(shí)次酌,由于索引和 HEAD 不同,若運(yùn)行
git status
的話就會(huì)看到 “Changes to be committed” 下的該文件變?yōu)榫G色.
也就是說(shuō)厨喂,現(xiàn)在預(yù)期的下一次提交與上一次提交不同和措。 最后,我們運(yùn)行git commit
來(lái)完成提交蜕煌。現(xiàn)在運(yùn)行
git status
會(huì)沒(méi)有輸出派阱,因?yàn)槿脴?shù)又變得相同了。
切換分支或克隆的過(guò)程也類似斜纪。 當(dāng)檢出一個(gè)分支時(shí)贫母,它會(huì)修改 HEAD 指向新的分支引用,
將 索引 填充為該次提交的快照盒刚,然后將 索引 的內(nèi)容復(fù)制到 工作目錄 中腺劣。
git重置git reset
,代碼回退操作介紹
1. 只移動(dòng)HEAD(相當(dāng)于取消上一次提交):git reset --soft HEAD~
或 git reset --soft 99ad0ec
reset
做的第一件事是移動(dòng)HEAD
的指向因块。reset
移動(dòng)HEAD
指向的分支橘原。
reset --soft
本質(zhì)上是撤銷了上一次git commit
命令。 當(dāng)你在運(yùn)行git commit
時(shí)涡上,Git
會(huì)創(chuàng)建一個(gè)新的提交趾断,
并移動(dòng)HEAD
所指向的分支來(lái)使其指向該提交。當(dāng)你將它reset
回HEAD~
HEAD 的父結(jié)點(diǎn))時(shí)吩愧,
其實(shí)就是把該分支移動(dòng)回原來(lái)的位置芋酌,而不會(huì)改變索引和工作目錄。
現(xiàn)在你可以更新索引并再次運(yùn)行git commit
來(lái)完成git commit --amend
所要做的事情了雁佳。
2. 移動(dòng)HEAD脐帝,更新index: git reset HEAD~
或git reset --mixed HEAD~
它依然會(huì)撤銷一上次 提交,但還會(huì) 取消暫存 所有的東西糖权。 于是堵腹,我們回滾到了所有git add
和git commit
的命令執(zhí)行之前。
3. 移動(dòng)HEAD星澳,更新index,更新工作目錄(working Directory): git reset --hard HEAD~
必須注意秸滴,--hard
標(biāo)記是reset
命令唯一的危險(xiǎn)用法,它也是Git
會(huì)真正地銷毀數(shù)據(jù)的僅有的幾個(gè)操作之一募判。
其他任何形式的reset
調(diào)用都可以輕松撤消荡含,但是--hard
選項(xiàng)不能,因?yàn)樗鼜?qiáng)制覆蓋了工作目錄中的文件届垫。
在這種特殊情況下释液,我們的Git
數(shù)據(jù)庫(kù)中的一個(gè)提交內(nèi)還留有該文件的v3
版本,我們可以通過(guò)reflog
來(lái)找回它装处。
但是若該文件還未提交误债,Git
仍會(huì)覆蓋它從而導(dǎo)致無(wú)法恢復(fù)。
reset
命令會(huì)以特定的順序重寫這三棵樹(shù)妄迁,在你指定以下選項(xiàng)時(shí)停止:
移動(dòng) HEAD 分支的指向 (若指定了 --soft寝蹈,則到此停止)
使索引看起來(lái)像 HEAD (若未指定 --hard,則到此停止)
使工作目錄看起來(lái)像索引
4. 使用git reflog
命令來(lái)查看所有已經(jīng)提交過(guò)的commit
5. 通過(guò)路徑來(lái)重置:git reset file.txt
假如我們運(yùn)行git reset file.txt
(這其實(shí)是git reset --mixed HEAD file.txt
的簡(jiǎn)寫形式登淘,
因?yàn)槟慵葲](méi)有指定一個(gè)提交的SHA-1
或分支箫老,也沒(méi)有指定--soft
或--hard
),它會(huì):
移動(dòng)
HEAD
分支的指向 (已跳過(guò))讓索引看起來(lái)像
HEAD
(到此處停止)
所以它本質(zhì)上只是將file.txt
從HEAD
復(fù)制到索引中黔州。
它還有取消暫存文件的實(shí)際效果耍鬓。
我們可以不讓Git從HEAD拉取數(shù)據(jù),而是通過(guò)具體指定一個(gè)提交來(lái)拉取該文件的對(duì)應(yīng)版本流妻。
我們只需運(yùn)行類似于git reset eb43bf file.txt
的命令即可牲蜀。
git checkout
介紹
切換分支:git checkout [分支名]
運(yùn)行git checkout [branch]
與運(yùn)行git reset --hard [branch]
非常相似,
它會(huì)更新所有三棵樹(shù)使其看起來(lái)像 [branch]绅这,不過(guò)有兩點(diǎn)重要的區(qū)別涣达。
首先不同于reset --hard
,checkout
對(duì)工作目錄是安全的证薇,它會(huì)通過(guò)檢查來(lái)確保不會(huì)將已更改的文件弄丟度苔。
其實(shí)它還更聰明一些。它會(huì)在工作目錄中先試著簡(jiǎn)單合并一下棕叫,這樣所有還未修改過(guò)的
文件都會(huì)被更新林螃。
而reset --hard
則會(huì)不做檢查就全面地替換所有東西。
第二個(gè)重要的區(qū)別是如何更新HEAD
俺泣。reset
會(huì)移動(dòng)HEAD
分支的指向疗认,而checkout
只會(huì)移動(dòng)HEAD
自身來(lái)指向另一個(gè)分支。
例如伏钠,假設(shè)我們有master
和develop
分支横漏,它們分別指向不同的提交;我們現(xiàn)在在develop
上(所以HEAD
指向它)熟掂。
如果我們運(yùn)行git reset master
切平,那么develop
自身現(xiàn)在會(huì)和master
指向同一個(gè)提交仗扬。
而如果我們運(yùn)行git checkout master
的話,develop
不會(huì)移動(dòng)耗美,HEAD
自身會(huì)移動(dòng)。 現(xiàn)在HEAD
將會(huì)指向master
咪惠。
所以,雖然在這兩種情況下我們都移動(dòng)HEAD
使其指向了提交 A,但做法是非常不同的刊愚。
reset 會(huì)移動(dòng)HEAD
分支的指向,而checkout
則移動(dòng)HEAD
自身踩验。
放棄index與working Directory的改動(dòng):git checkout [分支名] file.txt
該命令不會(huì)移動(dòng)HEAD鸥诽,只會(huì)把HEAD中的代碼恢復(fù)到index中,同時(shí)把工作目錄文件也恢復(fù)到HEAD中代碼的樣子箕憾。
值放棄修改working Directory 工作目錄中的修改:git checkout file.txt
放棄單個(gè)修改或使用git checkout .
放棄所有修改
這個(gè)命令只會(huì)放棄工作目錄中的修改牡借,已經(jīng)提交到index中的修改則不會(huì)改動(dòng)。