Git簡易教程

來源:互聯網
上載者:User

標籤:

概述

在說明什麼是git之前,我們需要對版本控制(Version Control)做一個基本的概述,一般情況下,我們的原始碼都是在時間和空間兩個維度上進行管理並維護的,代碼本身

以及組織代碼的專案檔(如makefile或者vs的專案檔)都是以檔案和目錄的形式儲存在磁碟空間上的,這種檔案管理的形式已經被大家所熟悉了,然而,我們在不同時間段裡做出的各種修改怎麼管理呢?版本控制系統 (Version Control System,以下簡稱VCS)就是一種記錄代碼修改演化的系統,他的功能就是方便你今後找回某個特定時期(或版本)的檔案、查看版本之間發生了哪些變化、對變化進行比較或者是修正致命錯誤。

版本控制系統主要經曆了本地版本控制,集中式版本控制到分布式版本控制的發展:

  • 本地版本控制(Local Version Control System)顧名思義就是本地化的版本控制系統,沒有網路協作等較為先進的版本控制的概念。
  • 集中式版本控制(Centralized Version Control System)為有一台版本控制伺服器運行在那邊存放並提供一個項目中所有版本檔案的服務,在很長一段時間內佔據主流,其中CVS與SVN為其代表。
  • 分布式版本控制(Distributed Version Control System)克服了集中式版本控制可能因為單點失敗造成的巨大損失的缺點,讓每一台用戶端在每一次checkout操作後都完全鏡像整個版本控制中的項目。在分布式版本控制系統中,任何一台機器都可以視為版本控制伺服器。即使有一台伺服器失去服務能力,其它機器與系統可以繼續協作維持版本控制系統的正常運轉。git就是分布式版本控制系統。

git與其它主流的VCS最大的區別就是,在項目版本更新的過程中,git記錄的並非是基於初始檔案的變化資料,而是通過一系列快照(Snapshot,就像是個小型的檔案系統)來儲存記錄每個檔案。如果有些檔案在版本更新後沒有發生任何變化,那麼在新的版本中它會是一個指向最近一次更新的檔案版本的連結。 此外,幾乎所有git的操作都是在本地進行的,所以,沒有了"延遲",幾乎所有的操作都是瞬間完成的。例如,當你想要查看項目曆史時,不需要特地去伺服器上抓取記錄,直接在本地瀏覽即可。這意味著,你可以在本地對比兩個不同版本的檔案的差別,可以在本地查看過去有哪些人對指定檔案作出了修改與更新,可以……幾乎完全本地化的操作也讓這樣一種情境成為了可能: 當有人由於沒有網路連接條件但是又必須抓緊時間對自己的項目進行修改與開發,同時又需要有版本管理系統來記錄每次他commit的曆史,這時,git提供了他所有需要的便利。

git使用SHA-1 Hash演算法加密產生的40位字串(而不是檔案名稱)來記錄代表git中的每樣東西。格式就像這樣:

??6bafcdc09f3d6d416f6572f82082987a486d3098

git中的檔案主要會處於三種狀態,它們分別是:

  • Committed: 檔案或資料已經安全的存放在了git本機資料庫中
  • Modified: 檔案或資料已經修改但是尚未commit到資料庫
  • Staged:檔案或資料已被標記要放入到下一次commit中

這樣的機制致使git的鏡像會由三個部分組成(假設有一個git目錄叫git-repo):

  • Git directory: 存放項目中所有中繼資料以及對象的地方(git-repo/.git/)
  • Working directory: 在這裡是從git項目資料庫中checkout出的一個單獨的(預設情況下是最新的)項目版本,用於對指定項目版本中的檔案進行修改和編輯(git-repo/)
  • Staging area: 一般是存放在Git directory中的一個簡單的檔案,裡面存放著下一次需要commit的檔案的資訊(在git-repo/.git/中)
安裝與配置

Git可以安裝在各種作業系統下,下面以windows為例,linux系統和mac os系統的使用者可以尋找github.com上的help內容。

在windows下安裝git非常簡單,只要依次完成下面操作即可:

第一步:下載 msysgit(http://code.google.com/p/msysgit/),安裝時一般只需要保留預設選項, 只是要注意,不要使用putty作為用戶端,GitHub只支援openssh. 安裝完成後需要產生SSH Key。

第二步:配置ssh的key,在使用者目錄下(windows下通常是C:\Documents and Settings\<your_username>,其他系統通常都是/home/<your_username>)如果已經存在ssh的配置會存有一個.ssh目錄(是隱藏目錄),目錄下會存有兩個檔案(id_rsa, id_rsa.pub),將其備份一下,然後產生新的,這裡cygwin的命令序列如下

$ ssh-keygen -t rsa -C "<[email protected]>"
Enter file in which to save the key (/c/Users/<your_username>/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):<此處需要你為其設定一個密碼>
Enter same passphrase again:<重複一遍密碼>
Your identification has been saved in /c/Users/<your_username>/.ssh/id_rsa.
Your public key has been saved in /c/Users/<your_username>/.ssh/id_rsa.pub.
The key fingerprint is:
????e8:ae:60:8f:38:c2:98:1d:6d:84:60:8c:9e:dd:47:81 <[email protected]>

第三步:將Public Key 添加到你所需要提交的伺服器上(這裡以GitHub為例,其他伺服器的方式聯絡相關的管理員),開啟你的GitHub->SSH Public Key->點擊"Add another public key", 將你的public key(id_rsa.pub)的內容拷貝到GitHub中。

第四步:測試組態是否成功,同樣的,在cygwin裡如此輸入:

$ ssh [email protected]
ERROR: Hi <your_username> You‘ve successfully authenticated, but GitHub does not provide
shell access
Connection to github.com closed.

看到以上資訊表示操作成功,接下來,我們可以學習一些基本使用。

本地基本操作

首先我們要初始化一個Repository,如果完全是建立一個項目,我們可以:

mkdir test
cd test
git init

這個時候,test目錄下就會多出一個叫做.git的目錄,該目錄下會有個config檔案,他的內容如下:

[core]
????repositoryformatversion = 0
????filemode = true
????bare = false
????logallrefupdates = true

我們需要加入自己的使用者資訊(注意,該資訊必須與你配置ssh的時候的資訊保持一致):

[user]
????name = <your_username>
????email = <[email protected]>????

當然,使用者資訊我們完全可以用命令列來配置,在git init命令之前輸入如下命令:

git config –global user.name "your_username"
git config –global user.email "[email protected]"

如果項目目錄已經存在,我們可以直接:

cd existing_git_repo
git init

接下來就是一些基本的操作了……

首先要用的是:git status,該命令用於查看目前git鏡像的狀態,在使用git的過程中,我們將會反覆的使用到這個工具:

$ git status
# On branch master
#
# Initial commit
#

nothing to commit (create/copy files and use "git add" to track)

可以看出,git status給出了相當詳細的資訊,第一行中首先給出的是git的分支(branch)狀態資訊,接著,git會告訴你現在還沒有東西提交到鏡像中,建議先使用命令git add來對檔案進行追蹤。所以,接下來我們介紹git add命令, 假設在的工作目錄中使用python語言寫一個helloworld的小程式,將代碼儲存完成後,我們得到一個hello.py檔案,然後,我們希望將這個檔案被git鏡像追蹤(track)到,那麼只需要:

$ git add hello.py

這樣,我們就將hello.py加入到了git鏡像中去進資料列版本設定,再次使用git status來查看目前的鏡像狀態:

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm –cached …" to unstage)
#
# new file: hello.py
#

注意,這裡它提到了changes to be committed,意思是該檔案已經處於staged狀態,接下去你可以根據自己的需要將其提交(commit),或者如果你覺得這是一個誤操作,該檔案不應當被提交,你可以通過git rm –cached命令來取消它的staged狀態(你會發現status資訊中給出了精確的提示)。

現在,我們通過命令git commit將hello.py提交:

$ git commit

這時,會出現一個帶有status資訊的文本給你編輯(使用什麼編輯器取決於你對git的配置),在以"#"開頭的注釋行下輸入一些文本,用於注釋此次提交,方便於其他代碼共同作業者的維護與理解!

你也可以通過命令參數-m來直接輸入注釋內容,加快提交速度:

$ git commit -m "comment here"

至此,你的檔案hello.py已經處於tracked狀態!。

現在,我們有一個hello.py在鏡像中了,接下來,假設發現了一個小錯誤,額,比如一個迴圈的條件寫錯了,於是我們需要針對檔案完成修改,之後,當我們再次git status的時候:

# On branch master
# Changed but not updated:
# (use "git add …" to update what will be committed)# (use "git che
# ckout — …" to discard changes in working directory)
#
# modified: hello.py
# no changes added to commit (use "git add" and/or "git commit -a")

git status顯示,hello.py被修改過了,如果你想要提交,需要再次git add該檔案,或者,可以直接使用git commit -a跳過add的步驟,直接提交(尚未track的檔案必須先git add才能進行提交)。

在提示中,還有提到說,如果你想撤銷對hello.py的修改,就可以使用git checkout命令來實現,這裡的情況會是:

$ git checkout – hello.py

如果你這麼做了,你就會發現,你的hello.py又回到了之前沒有被修改過的時候的狀態。在Unix/Unix-like系統中,幾乎都會有一個小巧的對比檔案不同的工具叫做diff,在git中也有這麼一個工具,來詳細比較你修改後準備提交的檔案與修改前的狀態的不同之處,恩,也許你猜到了,這個命令就是git diff。

現在我們嘗試著再次修改一下hello.py,然後運行git diff:

$ git diff
diff –git a/ hello.py b/ hello.py
index befc634..a86316b 100644
— a/hello.py
+++ b/hello.py
@@ -1,3 +1,4 @@
+/* new comment line */
if __name__ == "__main__":
print "hello, world!"

通過git的diff工具,很容易瞭解到我們更改了哪些地方。這個時候,如果我們想撤銷之前的更改,可以使用git reset命令:

$ git reset HEAD hello.py
$ git status
# On branch master
# Untracked files:
# (use "git add …" to include in what will be committed)
#
# hello.py

nothing added to commit but untracked files present (use "git add" to track)

再次git status,hello.py又回到了untracked狀態!

接下來,如果需要修改README.txt(通常是項目的讀我檔案)的檔案名稱(千萬要記得我們的檔案在git的鏡像中進資料列版本設定管理,不要魯莽的直接使用unix命令mv或者rm來對git鏡像中的檔案進行普通的檔案操作),我們該使用git mv命令:

$ git mv README.txt tutorial.txt
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD …" to unstage)
#
# renamed: README.txt -> tutorial.txt
#
$ git commit -a -m "renamed a file"
[master 55ce30d] renamed a file
1 files changed, 0 insertions(+), 0 deletions(-)
rename README.txt => tutorial.txt (100%)

可以看到,在提交變更後,README.txt在檔案系統以及git鏡像中都被成功地重新命名為了tutorial.txt。同樣的,你可以unstage來撤銷對該檔案的重新命名,the choice is yours!

如果我們不再需要tutorial.txt這個檔案,我們可以將其從git鏡像中刪除,git中刪除檔案的命令是git rm:

$ git rm tutorial.txt
rm ‘tutorial.txt‘
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD …" to unstage)
#
# deleted: tutorial.txt
#
$ git commit -a -m " deleted a file"
[master 7d81981] deleted a file
1 files changed, 0 insertions(+), 1 deletions(-)
delete mode 100644 tutorial.txt????

正如之前所提到的,這些操作都是可以恢複的,因為git是版本控制系統,所以自然而然的就會有一套版本曆史管理機制。

我們可以用工具git log提供了查看git鏡像的commit曆史:

$ git log
commit 7d819818530ce89322019ba5000723c973eb0420
Author: ghosTM55
Date: Sun Mar 14 15:26:22 2010 +0800

deleted a file

commit 55ce30d88fb5c81d20bdf86e2034053613fed632
Author: ghosTM55
Date: Sun Mar 14 15:11:39 2010 +0800
renamed a file
commit 2ed9f1f9bd1a7561cd7e57dcdbd7f2cda54668fb
Author: ghosTM55
Date: Sun Mar 14 14:58:11 2010 +0800
a little change

基本上可以清楚地看到,git詳細記錄了每次commit的資訊(checksum值、提交者資訊、提交時間)。

下面簡單的說一下分支管理的操作,git的分支管理是異常的簡單和方便,可以用git branch命令進行非常直觀的操作:

首先可以在工作目錄下查看當前的項目存在多少分支:

$ git branch
* master
test

可以清楚地看到,目前該項目存在兩個分支master和test,帶*的是當前分支(我們可以用命令git checkout test切換到test反之)。接下來我們為項目添加一個分支:

$ git branch new
$ git branch
* master
new
test

我們看到新分支new已經添加進git的鏡像裡了,如果要刪除該分支,我們可以如此:

$ git branch -d new
Deleted branch new (was 63c0da1).
$ git branch
* master
test

這時候我們就看到new已不在鏡像中,當我們需要將指定分支中的代碼合并到預設分支的時候,可以使用命令:

遠程基本操作

(這部分引用一個網路blog:http://archive.cnblogs.com/a/2050324/)

要參與任何一個 Git 項目的協作,必須要瞭解該如何管理遠程倉庫。遠程倉庫是指託管在網路上的項目倉庫,可能會有好多個,其中有些你只能讀,另外有些可以寫。同他人協作開發某 個項目時,需要管理這些遠程倉庫,以便推送或拉取資料,分享各自的工作進展。管理遠程倉庫的工作,包括添加遠程庫,移除廢棄的遠程庫,管理各式遠程庫分支,定義是否跟蹤這些分支,等等。本節我們將詳細討論遠程庫的管理和使用。

查看當前的遠程庫

要查看當前配置有哪些遠程倉庫,可以用 git remote 命令,它會列出每個遠程庫的簡短名字。在複製完某個項目後,至少可以看到一個名為 origin 的遠程庫,Git 預設使用這個名字來標識你所複製的原始倉庫:

$ git clone git://github.com/schacon/ticgit.git
Initialized empty Git repository in /private/tmp/ticgit/.git/
remote: Counting objects: 595, done.
remote: Compressing objects: 100% (269/269), done.
remote: Total 595 (delta 255), reused 589 (delta 253)
Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done.
Resolving deltas: 100% (255/255), done.
$ cd ticgit
$ git remote
origin

也可以加上 -v 選項(譯註:此為 –verbose 的簡寫,取首字母),顯示對應的複製地址:

$ git remote –v
origin git://github.com/schacon/ticgit.git

如果有多個遠程倉庫,此命令將全部列出。比如在我的 Grit 項目中,可以看到:

$ cd grit
$ git remote –v
bakkdoor git://github.com/bakkdoor/grit.git
cho45 git://github.com/cho45/grit.git
defunkt git://github.com/defunkt/grit.git
koke git://github.com/koke/grit.git
origin [email protected]:mojombo/grit.git

這樣一來,我就可以非常輕鬆地從這些使用者的倉庫中,拉取他們的提交到本地。請注意,上面列出的地址只有 origin 用的是 SSH URL 連結,所以也只有這個倉庫我能推送

資料上去(我們會在第四章解釋原因)。

添加遠程倉庫

要添加一個新的遠程倉庫,可以指定一個簡單的名字,以便將來引用,運行 git remote add [shortname] [url]:

$ git remote
origin
$ git remote add pb git://github.com/paulboone/ticgit.git
$ git remote –v
origin git://github.com/schacon/ticgit.git
pb git://github.com/paulboone/ticgit.git

現在可以用字串 pb 指代對應的倉庫地址了。比如說,要抓取所有 Paul 有的,但本地倉庫沒有的資訊,可以運行 git fetch pb:

$ git fetch pb
remote: Counting objects: 58, done.
remote: Compressing objects: 100% (41/41), done.
remote: Total 44 (delta 24), reused 1 (delta 0)
Unpacking objects: 100% (44/44), done.
From git://github.com/paulboone/ticgit
* [new branch] master -> pb/master
* [new branch] ticgit -> pb/ticgit

現在,Paul 的主幹分支(master)已經完全可以在本地訪問了,對應的名字是 pb/master,你可以將它合并到自己的某個分支,或者切換到這個分支,看看有些什麼有趣的更新。

從遠程倉庫抓取資料

正如之前所看到的,可以用下面的命令從遠程倉庫抓取資料到本地:

$ git fetch [remote-name]

此命令會到遠程倉庫中拉取所有你本地倉庫中還沒有的資料。運行完成後,你就可以在本地訪問該遠程倉庫中的所有分支,將其中某個分支合并到本地,或者只是取出某個分支,一探究竟。(我們會在第三章詳細討論關於分支的概念和操作。)

如果是複製了一個倉庫,此命令會自動將遠程倉庫歸於 origin 名下。所以,git fetch origin 會抓取從你上次複製以來別人上傳到此遠程倉庫中的所有更新(或是上次fetch 以來別人提交的更新)。有一點很重要,需要記住,fetch 命令只是將遠端的資料拉到本地倉庫,並不自動合并到當前工作分支,只有當你確實準備好了,才能手工合并。(說明:事先需要建立好遠端倉庫,然後執行:git remote add [倉庫名] [倉庫url],git fetch [遠程倉庫名],即可抓取到遠程倉庫資料到本地,再用git merge remotes/[倉庫名]/master就可以將遠程倉庫merge到本地當前branch。這種分支方式比較適合獨立-整合開發,即各自開發測試好後 再整合在一起。比如,Android的Framework和AP開發。

可以使用–bare 選項運行git init 來設定一個空倉庫,這會初始化一個不包含工作目錄的倉庫。

$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git –bare init

這時,Join,Josie 或者Jessica 就可以把它加為遠程倉庫,推送一個分支,從而把第一個版本的工程上傳到倉庫裡了。)

如果設定了某個分支用於跟蹤某個遠端倉庫的分支(參見下節及第三章的內容),可以使用 git pull 命令自動抓取資料下來,然後將遠端分支自動合并到本地倉庫中當前分支。在日常工作中我們經常這麼用,既快且好。實際上,預設情況下 git clone 命令本質上就是自動建立了本地的 master 分支用於跟蹤遠程倉庫中的 master 分支(假設遠程倉庫確實有 master 分支)。所以一般我們運行 git pull,目的都是要從原始複製的遠端倉庫中抓取資料後,合并到工作目錄中當前分支。

推送資料到遠程倉庫

項目進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的資料推送到遠程倉庫。實現這個任務的命令很簡單: git push [remote-name] [branch-name]。如果要把本地的 master 分支推送到 origin 伺服器上(再次說明下,複製操作會自動使用預設的 master 和 origin 名字),可以運行下面的命令:

$ git push origin master

只有在所複製的伺服器上有寫入權限,或者同一時刻沒有其他人在推資料,這條命令才會如期完成任務。如果在你推資料前,已經有其他人推送了若干更新,那你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,併到自己的項目中,然後才可以再次推送。有關推送資料到遠程倉庫的詳細內容見第三章。

查看遠程倉庫資訊

我們可以通過命令 git remote show [remote-name] 查看某個遠程倉庫的詳細資料,比如要看所複製的origin 倉庫,可以運行:

$ git remote show origin
* remote origin
URL: git://github.com/schacon/ticgit.git
Remote branch merged with ‘git pull‘ while on branch master
master
Tracked remote branches
master
ticgit

除了對應的複製地址外,它還給出了許多額外的資訊。它友善地告訴你如果是在 master 分支,就可以用git pull命令抓取資料合併到本地。另外還列出了所有處於跟蹤狀態中的遠端分支。

在實際使用過程中,git remote show 給出的資訊可能會像這樣:

$ git remote show origin
* remote origin
URL: [email protected]:defunkt/github.git
Remote branch merged with ‘git pull‘ while on branch issues
issues
Remote branch merged with ‘git pull‘ while on branch master
master
New remote branches (next fetch will store in remotes/origin)
caching
Stale tracking branches (use ‘git remote prune‘)
libwalker
walker2
Tracked remote branches
acl
apiv2
dashboard2
issues
master
postgres
Local branch pushed with ‘git push‘
master:master

它告訴我們,運行 git push 時預設推送的分支是什麼(譯註:最後兩行)。它還顯示了有哪些遠端分支還沒有同步 到本地(譯註:第六行的 caching 分支),哪些已同步到本地的遠端分支在遠端伺服器上已被刪除(譯註:Stale tracking branches 下面的兩個分支),以及運行 git pull 時將自動合并哪些分支(譯註:前四行中列出的 issues 和 master 分支)。(此命令也可以查看到本地分支和遠程倉庫分支的對應關係。)

遠程倉庫的刪除和重新命名

在新版 Git 中可以用 git remote rename 命令修改某個遠程倉庫的簡簡短名稱,比如想把 pb 改成 paul,可以這麼運行:

$ git remote rename pb paul
$ git remote
origin
paul

注意,對遠程倉庫的重新命名,也會使對應的分支名稱發生變化,原來的 pb/master分支現在成了paul/master。

碰到遠端倉程式庫伺服器遷移,或者原來的複製鏡像不再使用,又或者某個參與者不再貢獻代碼,那麼需要移除對應的遠端倉庫,可以運行 git remote rm 命令:

$ git remote rm paul
$ git remote
Origin

推薦書籍

《版本控制之道——使用Git》

副標題: —使用Git

作者: Travis Swicegood

譯者: 董越 / 付昭偉 / 等譯

出版社: 電子工業出版社

出版年: 2010年5月

?

《Git權威指南》

作者: 蔣鑫

出版社: 機械工業出版社華章公司

出版年: 2011年6月

?

?

Git簡易教程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.