第 2 章 基本技巧

2018-02-24 15:45 更新

與其一頭扎進(jìn)Git命令的海洋中,不如來點(diǎn)基本的例子試試手。它們簡(jiǎn)單而且實(shí)用。實(shí)際 上,在開始使用Git的頭幾個(gè)月,我所用的從來沒超出本章介紹的內(nèi)容。

保存狀態(tài)

要不來點(diǎn)猛的?在做之前,先為當(dāng)前目錄所有文件做個(gè)快照,使用:

$ git init
$ git add .
$ git commit -m "My first backup"

現(xiàn)在如果你的編輯亂了套,恢復(fù)之前的版本:

$ git reset --hard

再次保存狀態(tài):

$ git commit -a -m "Another backup"

添加、刪除、重命名

以上命令將只跟蹤你第一次運(yùn)行?git add?命令時(shí)就已經(jīng)存在的文件。如果要添加新文 件或子目錄,你需要告訴Git:

$ git add readme.txt Documentation

類似,如果你想讓Git忘記某些文件:

$ git rm kludge.h obsolete.c
$ git rm -r incriminating/evidence/

這些文件如果還沒刪除,Git刪除它們。

重命名文件和先刪除舊文件,再添加新文件的一樣。也有一個(gè)快捷方式?git mv?,和?mv?命令的用法一樣。例如:

$ git mv bug.c feature.c

進(jìn)階撤銷/重做

有時(shí)候你只想把某個(gè)時(shí)間點(diǎn)之后的所有改動(dòng)都回滾掉,因?yàn)檫@些的改動(dòng)是不正確的。那 么:

$ git log

來顯示最近提交列表,以及他們的SHA1哈希值:

commit 766f9881690d240ba334153047649b8b8f11c664
Author: Bob <bob@example.com>
Date:   Tue Mar 14 01:59:26 2000 -0800

    Replace printf() with write().

commit 82f5ea346a2e651544956a8653c0f58dc151275c
Author: Alice <alice@example.com>
Date:   Thu Jan 1 00:00:00 1970 +0000

    Initial commit.

哈希值的前幾個(gè)字符足夠確定一個(gè)提交;也可以拷貝粘貼完整的哈希值,鍵入:

$ git reset --hard 766f

來恢復(fù)到一個(gè)指定的提交狀態(tài),并從記錄里永久抹掉所有比該記錄新一些的提交。

另一些時(shí)候你想簡(jiǎn)單地跳到一個(gè)舊狀態(tài)。這種情況,鍵入:

$ git checkout 82f5

這個(gè)操作將把你帶回過去,同時(shí)也保留較新提交。然而,像科幻電影里時(shí)光旅行一樣, 如果你這時(shí)編輯并提交的話,你將身處另一個(gè)現(xiàn)實(shí)里,因?yàn)槟愕膭?dòng)作與開始時(shí)相比是不 同的。

這另一個(gè)現(xiàn)實(shí)叫作“分支”(branch),之后?我們會(huì)對(duì)這點(diǎn)多討論一些。 至于現(xiàn)在,只要記?。?/p>

$ git checkout master

會(huì)把你帶到當(dāng)下來就可以了。另外,為避免Git的抱怨,應(yīng)該在每次運(yùn)行checkout之前提 交(commit)或重置(reset)你的改動(dòng)。

還以電腦游戲作為類比:

  • git reset --hard: 加載一個(gè)舊記錄并刪除所有比之新的記錄。
  • git checkout: 加載一個(gè)舊記錄,但如果你在這個(gè)記錄上玩,游戲狀態(tài)將偏離第 一輪的較新狀態(tài)。你現(xiàn)在打的所有游戲記錄會(huì)在你剛進(jìn)入的、代表另一個(gè)真實(shí)的分支 里。我們稍后論述。

你可以選擇只恢復(fù)特定文件和目錄,通過將其加在命令之后:

$ git checkout 82f5 some.file another.file

小心,這種形式的?checkout?會(huì)不聲不響地覆蓋文件。為阻止意外發(fā)生,在運(yùn)行任何 checkout命令之前做提交,尤其在初學(xué)Git的時(shí)候。通常,任何時(shí)候你覺得對(duì)運(yùn)行某個(gè)命 令不放心,無論Git命令還是不是Git命令,就先運(yùn)行一下?git commit -a?。

不喜歡拷貝站題哈希值?那就用:

$ git checkout :/"My first b"

來跳到以特定字符串開頭的提交。你也可以回到倒數(shù)第五個(gè)保存狀態(tài):

$ git checkout master~5

撤銷

在法庭上,事件可以從法庭記錄里敲出來。同樣,你可以檢出特定提交以撤銷。

$ git commit -a
$ git revert 1b6d

講撤銷給定哈希值的提交。本撤銷被記錄為一個(gè)新的提交,你可以通過運(yùn)行?git log?來確認(rèn)這一點(diǎn)。

變更日志生成

一些項(xiàng)目要求生成變更日志changelog. 生 成一個(gè),通過鍵入:

$ git log > ChangeLog

下載文件

得到一個(gè)由Git管理的項(xiàng)目的拷貝,通過鍵入:

$ git clone git://server/path/to/files

例如,得到我用來創(chuàng)建該站的所有文件:

$ git clone git://git.or.cz/gitmagic.git

我們很快會(huì)對(duì)?clone?命令談的很多。

到最新

如果你已經(jīng)使用?git clone?命令得到了一個(gè)項(xiàng)目的一份拷貝,你可以更新到最新版, 通過:

$ git pull

快速發(fā)布

假設(shè)你寫了一個(gè)腳本,想和他人分享。你可以只告訴他們從你的計(jì)算機(jī)下載,但如果此 時(shí)你正在改進(jìn)你的腳本,或加入試驗(yàn)性質(zhì)的改動(dòng),他們下載了你的腳本,他們可能由此 陷入困境。當(dāng)然,這就是發(fā)布周期存在的原因。開發(fā)人員可能頻繁進(jìn)行項(xiàng)目修改,但他 們只在他們覺得代碼可以見人的時(shí)候才擇時(shí)發(fā)布。

用Git來完成這項(xiàng),需要進(jìn)入你的腳本所在目錄:

$ git init
$ git add .
$ git commit -m "First release"

然后告訴你的用戶去運(yùn)行:

$ git clone your.computer:/path/to/script

來下載你的腳本。這要假定他們有ssh訪問權(quán)限。如果沒有,需要運(yùn)行?git daemon?并 告訴你的用戶去運(yùn)行:

$ git clone git://your.computer/path/to/script

從現(xiàn)在開始,每次你的腳本準(zhǔn)備好發(fā)布時(shí),就運(yùn)行:

$ git commit -a -m "Next release"

并且你的用戶可以通過進(jìn)入包含你腳本的目錄,并鍵入下列命令,來更新他們的版本:

$ git pull

你的用戶永遠(yuǎn)也不會(huì)取到你不想讓他們看到的腳本版本。顯然這個(gè)技巧對(duì)所有的東西都 是可以,不僅是對(duì)腳本。

我們已經(jīng)做了什么?

找出自從上次提交之后你已經(jīng)做了什么改變:

$ git diff

或者自昨天的改變:

$ git diff "@{yesterday}"

或者一個(gè)特定版本與倒數(shù)第二個(gè)變更之間:

$ git diff 1b6d "master~2"

輸出結(jié)果都是補(bǔ)丁格式,可以用?git apply?來把補(bǔ)丁打上。也可以試一下:

$ git whatchanged --since="2 weeks ago"

我也經(jīng)常用qgit?瀏覽歷史, 因?yàn)樗膱D形界 面很養(yǎng)眼,或者?tig?,一個(gè)文本界面的東西,很慢的網(wǎng) 絡(luò)狀況下也工作的很好。也可以安裝web 服務(wù)器,運(yùn)行?git instaweb?,就可以用任 何瀏覽器瀏覽了。

練習(xí)

比方A,B,C,D是四個(gè)連續(xù)的提交,其中B與A一樣,除了一些文件刪除了。我們想把這 些刪除的文件加回D。我們?nèi)绾巫龅竭@個(gè)呢?

至少有三個(gè)解決方案。假設(shè)我們?cè)贒:

  1. A與B的差別是那些刪除的文件。我們可以創(chuàng)建一個(gè)補(bǔ)丁代表這些差別,然后吧補(bǔ)丁 打上:

    $ git diff B A | git apply
  2. 既然這些文件存在A,我們可以把它們拿出來:

    $ git checkout A foo.c bar.h
  3. 我們可以把從A到B的變化視為可撤銷的變更:

    $ git revert B

哪個(gè)選擇最好?這取決于你的喜好。利用Git滿足自己需求是容易,經(jīng)常還有多個(gè)方法。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)