git學習總結

jopen 10年前發布 | 19K 次閱讀 Git 版本控制系統

優點:
支持離線工作;本地提交可以稍后提交到服務器上。
Git 中的每個工作樹都包含一個具有完整項目歷史的倉庫。
沒有哪一個 Git 倉庫會天生比其他倉庫更重要。
Git 跟SVN一樣有自己的集中式版本庫或服務器。
Git是分布式的,SVN不是,這是Git和其它非分布式的版本控制系統(SVN,CVS)最核心的區別。

Git與SVN 的區別
每個開發人員從中心版本庫的服務器上check out代碼后會在自己的機器上克隆一個自己的版本庫。
如果你被困在一個不能連接網絡的地方時,就像在飛機上,地下室,電梯里等,你仍然能夠提交文件,查看歷史版本記錄,創建項目分支等。(無網絡也能)
開源軟件:創建一個分支,向項目團隊發送一個推請求。就能將你的代碼發送給項目團隊。
.git 目錄是處于你的機器上的一個克隆版的版本庫,它擁有中心版本庫上所有的東西,例如標簽、分支、版本記錄等。
Git 分支和SVN的分支不同:分支在SVN中一點不特別,就是版本庫中的另外的一個目錄。如果你想知道是否合并了一個分支,你需要手工運行像這樣的命令svn propget svn:mergeinfo,來確認代碼是否被合并。
git:你可以從同一個工作目錄下快速的在幾個分支間切換。你很容易發現未被合并的分支,你能簡單而快捷的合并這些文件。
SVN的版本號實際是任何一個相應時間的源代碼快照,它是從CVS進化到SVN的最大的一個突破。
Git 可以使用SHA-1來唯一的標識一個代碼快照
Git 的內容完整性要優于SVN
Git 的內容存儲使用的是SHA-1哈希算法。這能確保代碼內容的完整性,確保在遇到磁盤故障和網絡問題時降低對版本庫的破壞。


CVS-SVN-GIT綜合比較
(1)版本庫模型:有客戶端/服務器和分布式兩種模式。
在客戶端/服務器模式下,每一用戶通過客戶端訪問位于服務器的主版本庫,每一客戶機只需保存它所關注的文件副本,對當前工作副本(working copy)的更改只有在提交到服務器之后,其它用戶才能看到對應文件的修改。
分布式模式下,這些源碼版本庫副本間是對等的實體,用戶的機器出了保存他們的工作副本外,還擁有本地版本庫的  歷史信息(歷史版本信息)  。
(2)并發模式:描述了當同時對同一工作副本/文件進行更改或編輯時,如何管理這種沖突以避免產生無意義的數據,有排它鎖和合并模式。
在排它鎖模式下,只有發出請求并獲得當前文件排它鎖的用戶才能對對該文件進行更改。
而在合并模式下,用戶可以隨意編輯或更改文件,但可能隨時會被通知存在沖突(兩個或多個用戶同時編輯同一文件),于是版本控制工具或用戶需要  合并更改  以解決這種沖突。
(3)歷史模式:描述了如何在版本庫中存貯文件的更改信息,有快照和改變集兩種模式。
在快照模式下,版本庫會分別存儲更改發生前后的工作副本;
在改變集模式下,版本庫除了保存更改發生前的工作副本外,只保存更改發生后的改變信息。
(4)變更范圍
描述了版本編號是針對單個文件還是整個目錄樹。
(5)網絡協議
描述了多個版本庫間進行同步時采用的網絡協議。
(6)原子提交性
描述了在提交更改時,能否保證所有更改要么全部提交或合并,要么不會發生任何改變。
(7)部分克隆
是否支持只拷貝版本庫中特定的子目錄。

名稱  版本庫模型    并發模式         歷史模式         變更范圍  網絡協議   原子提交性 部分克隆
CVS  Client-server Merge Changeset File  Pserver,ssh No Yes
SVN  Client-server 3-way merge, recursive  Changeset and  custom (svn), custom (svn) over ssh,
merge, octopus merge Snapshot Tree  HTTP and SSL (usingWebDAV) Yes Yes


Git  Distributed    Merge or lock Snapshot Tree  custom, custom over ssh, rsync,
 HTTP/HTTPS, email, bundles Yes No
基礎命令:
初始化一個新的代碼倉庫:

第一種是在現存的目錄下,通過導入所有文件來創建新的 Git 倉庫。
在工作目錄中初始化新倉庫:要對現有的某個項目開始用 Git 管理,只需到此項目所在的目錄,執行:
$ git init
第二種是從已有的 Git 倉庫克隆出一個新的鏡像倉庫來。初次克隆某個倉庫時,工作目錄中的所有文件都屬于已跟蹤文件,且狀態為未修改。
這里克隆,Git 會自動為你將此遠程倉庫命名為 origin,并下載其中所有的數據,建立一個指向它的 master 分支的指針,在本地命名為 origin/master,但你無法在本地更改其(遠程倉庫)數據。
在克隆倉庫時,Git 通常會自動創建一個名為 master 的分支來跟蹤 origin/master。這正是 git push 和 git pull 一開始就能正常工作的原因。
接著,Git 建立一個屬于你自己的本地 master 分支,始于 origin 上 master 分支相同的位置,你可以就此開始工作。
從現有倉庫克隆,這里使用的是 clone 而不是 checkout。Git 收取的是項目歷史的所有數據(每一個文件的每一個版本),服務器上有的數據克隆之后本地也都有了。命令格式為 git clone [url],當前目錄下創建一個名為“grit”的目錄,其中包含一個 .git 的目錄
git clone 命令本質上就是自動創建了本地的 master 分支用于跟蹤遠程倉庫中的 master 分支(假設遠程倉庫確實有 master 分支)
(克隆操作會自動使用默認的 master 和 origin 名字)
拷貝一個 Git 倉庫到本地,讓自己能夠查看該項目,或者進行修改
$ git clone git://github.com/schacon/grit.git
如果希望在克隆的時候,自己定義要新建的項目目錄名稱,可以在上面的命令末尾指定新的名字:
$ git clone git://github.com/schacon/grit.git mygrit
做一些適當配置
開始或停止跟蹤某些文件:
如果當前目錄下有幾個文件想要納入版本控制,需要先用 git add 命令告訴 Git 開始對這些文件進行跟蹤,然后提交:
$ git add .c
$ git add README
$ git commit -m 'initial project version'
git add 的潛臺詞就是把目標文件快照放入暫存區域,也就是 add file into staged area,同時未曾跟蹤過的文件標記為需要跟蹤。

我們手上已經有了一個真實項目的 Git 倉庫,并從這個倉庫中取出了所有文件的工作拷貝。接下來,對這些文件作些修改,在完成了一個階段的目標之后,提交本次更新到倉庫。


檢查當前文件狀態
要確定哪些文件當前處于什么狀態,可以用 git status 命令。如果在克隆倉庫之后立即執行此命令,會看到類似這樣的輸出:
$ git status # On branch master nothing to commit (working directory clean)
當前沒有任何跟蹤著的文件
也沒有任何文件在上次提交后更改過
當前目錄下沒有出現任何處于未跟蹤的新文件,否則 Git 會在這里列出來。
顯示了當前所在的分支
會有以下兩種狀態:
Changes to be committed:處于staged的文件
Changed but not updated:處于modified的文件
注:一個文件可以同時處于上面兩種狀態,就是在加入staged的文件又被修改后
暫存或提交某些更新
修改下之前已跟蹤過的文件,出現在 “Changed but not updated” 這行下面,說明已跟蹤文件的內容發生了變化,但還沒有放到暫存區。
要暫存這次更新,需要運行git add 命令(這是個多功能命令,根據目標文件的狀態不同,此命令的效果也不同:可以用它開始跟蹤新文件,
或者把已跟蹤的文件放到暫存區,還能用于合并時把有沖突的文件標記為已解決狀態等)。
$ git add benchmarks.rb
提交更新,在此之前,請一定要確認還有什么修改過的或新建的文件還沒有 git add 過,否則提交的時候不會記錄這些還沒暫存起來的變化。
提交時記錄的是放在暫存區域的快照,任何還未暫存的仍然保持已修改狀態,可以在下次提交時納入版本管理。
每一次運行提交操作,都是對你項目作一次快照,以后可以回到這個狀態,或者進行比較。
Git 提供了一個跳過使用暫存區域的方式,只要在提交的時候,給 git commit 加上-a 選項,Git 就會自動把所有已經跟蹤過的文件暫存起來一并提交,從而跳過 git add 步驟:
$ git commit
$ git commit -m 'initial project version'
$ git commit -a -m 'added new benchmarks'

查看已暫存和未暫存的更新
git status 的顯示比較簡單,僅僅是列出了修改過的文件,如果要查看具體修改了什么地方,可以用 git diff 命令。
它已經能回答我們的兩個問題了:當前做的哪些更新還沒有暫存?有哪些更新已經暫存起來準備好了下次提交?
git diff 會使用文件補丁的格式顯示具體添加和刪除的行。
$ git diff
此命令比較的是工作目錄中當前文件和暫存區域快照之間的差異,也就是修改之后還沒有暫存起來的變化內容。
$ git diff --cached
要看已經暫存起來的文件和上次提交時的快照之間的差異,可以用 git diff --cached 命令。
移除文件
要從 Git 中移除某個文件,就必須要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),然后提交。
用 git rm 命令完成此項工作,并連帶從工作目錄中刪除指定的文件,這樣以后就不會出現在未跟蹤文件清單中了。
如果只是簡單地從工作目錄中手工刪除文件,運行 git status 時就會在 “Changed but not updated” 部分(也就是_未暫存_清單)
$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
刪除之前修改過并且已經放到暫存區域的話,則必須要用強制刪除選項 -f
$ git rm -f grit.gemspec
要移除跟蹤但不刪除文件,以便稍后在 .gitignore 文件中補上,用 --cached 選項即可
$ git rm --cached readme.txt
后面可以列出文件或者目錄的名字,也可以使用 glob 模式。比方說:
$ git rm log/\
.log
遞歸刪除當前目錄及其子目錄中所有 ~ 結尾的文件
$ git rm *~
僅僅刪除指定目錄下的文件而不會遞歸匹配。
$ git rm log/*.log
移動文件
要在 Git 中對文件改名
$ git mv file_from file_to
運行 git mv 就相當于運行了下面三條命令:
$ mv README.txt README $ git rm README.txt $ git add README
讓 Git 忽略某些文件,或是名稱符合特定模式的文件
我們總會有些文件無需納入 Git 的管理,也不希望它們總出現在未跟蹤文件列表。可以創建一個名為 .gitignore 的文件,列出要忽略的文件模式。要養成一開始就設置好 .gitignore 文件的習慣,以免將來誤提交這類無用的文件。
$ cat .gitignore .[oa] ~
第一行告訴 Git 忽略所有以 .o 或 .a 結尾的文件。
第二行告訴 Git 忽略所有以波浪符(~)結尾的文件
文件 .gitignore 的格式規范如下:

此為注釋 – 將被 Git 忽略

.a       # 忽略所有 .a 結尾的文件
!lib.a    # 但 lib.a 除外
/TODO     # 僅僅忽略項目根目錄下的 TODO 文件,不包括 subdir/TODO
build/    # 忽略 build/ 目錄下的所有文件
doc/
.txt # 會忽略 doc/notes.txt 但不包括 doc/server/arch.txt
● 所有空行或者以注釋符號 # 開頭的行都會被 Git 忽略。
● 可以使用標準的 glob 模式匹配。 匹配模式最后跟反斜杠(/)說明要忽略的是目錄。 要忽略指定模式以外的文件或目錄,可以在模式前加上驚嘆號(!)取反。
如何既快且容易地撤消犯下的小錯誤
修改最后一次提交,我們提交完了才發現漏掉了幾個文件沒有加,或者提交信息寫錯了。想要撤消剛才的提交操作,可以使用 --amend選項重新提交:
$ git commit --amend
剛才提交完沒有作任何改動,直接運行此命令的話,相當于有機會重新編輯提交說明,但將要提交的文件快照和之前的一樣。
$ git commit --amend -m 'message'
如果剛才提交時忘了暫存某些修改,可以先補上暫存操作,然后再運行 --amend 提交
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
上面的三條命令最終只是產生一個提交,第二個提交命令修正了第一個的提交內容。
取消已經暫存的文件
$ git reset HEAD benchmarks.rb
benchmarks.rb: locally modified
取消對文件的修改,該如何取消修改,回到之前的狀態(也就是修改之前的版本)呢?
$ git checkout -- benchmarks.rb
任何已經提交到 Git 的都可以被恢復。即便在已經刪除的分支中的提交,或者用 --amend 重新改寫的提交,都可以被恢復


如何瀏覽項目的更新歷史,查看某兩次更新之間的差異
查看提交歷史,在提交了若干更新之后,又或者克隆了某個項目,想回顧下提交歷史,可以使用 git log 命令查看
$ git log
常用 -p 選項展開顯示每次提交的內容差異,用 -2 則僅顯示最近的兩次更新:
$ git log -p -2
僅顯示簡要的增改行數統計
$ git log --stat
--pretty 選項,可以指定使用完全不同于默認格式的方式展示提交歷史。另外還有 short,full 和fuller 可以用
$ git log --pretty=oneline
定制要顯示的記錄格式
$ git log --pretty=format:"%h - %an, %ar : %s"
其他常用的選項及其釋義。
選項 說明
-p 按補丁格式顯示每個更新之間的差異。
--stat 顯示每次更新的文件修改統計信息。
--shortstat 只顯示 --stat 中最后的行數修改添加移除統計。
--name-only 僅在提交信息后顯示已修改的文件清單。
--name-status 顯示新增、修改、刪除的文件清單。
--abbrev-commit 僅顯示 SHA-1 的前幾個字符,而非所有的 40 個字符。
--relative-date 使用較短的相對時間顯示(比如,“2 weeks ago”)。
--graph 顯示 ASCII 圖形表示的分支合并歷史。
--pretty 使用其他格式顯示歷史提交信息。可用的選項包括 oneline,short,full,fuller 和 format(后跟指定格式)。
以及如何從遠程倉庫 拉數據下來或者推數據上去
使用圖形化工具查閱提交歷史
相當于 git log 命令的可視化版本,
在項目工作目錄中輸入 gitk 命令后,就會啟動,上半個窗口顯示的是歷次提交的分支祖先圖譜,下半個窗口顯示當前點選的提交對應的具體差異。


遠程倉庫的使用

查看當前的遠程庫
查看當前配置有哪些遠程倉庫,可以用 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
顯示對應的克隆地址
$ 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    git@ github.com:mojombo/grit.git

添加遠程倉庫
要添加一個新的遠程倉庫,可以指定一個簡單的名字,以便將來引用,運行 git remote add [shortname] [url]:
clone克隆就是默認名字為origin遠程倉庫名的遠程倉庫。
$ git remote add pb git://github.com/paulboone/ticgit.git


從遠程倉庫抓取數據
要抓取所有 遠程倉庫 有的,但本地倉庫沒有的信息,可以運行 git fetch pb:
fetch 命令只是將遠端的數據拉到本地倉庫,并不自動合并到當前工作分支,只有當你確實準備好了,才能手工合并。
$ git fetch [remote-name]
自動抓取數據下來,然后將遠端分支自動合并到本地倉庫中當前分支。
git pull 命令
在跟蹤分支里運行 git pull 會獲取所有遠程索引,并把它們的數據都合并到本地分支中來。
$ git pull


推送數據到遠程倉庫
要同別人分享目前的成果,可以將本地倉庫中的數據推送到遠程倉庫。實現這個任務的命令很簡單: git push [remote-name] [branch-name]。
如果要把本地的 master 分支推送到origin 服務器上,可以運行下面的命令:(克隆操作會自動使用默認的 master 和 origin 名字)
$ git push origin master
條件:只有在所克隆的服務器上有寫權限,或者同一時刻沒有其他人在推數據,這條命令才會如期完成任務。如果在你推數據前,已經有其他人推送了若干更新,那 你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,合并到自己的項目中,然后才可以再次推送。
跟蹤遠程分支:從遠程分支 checkout 出來的本地分支,稱為 跟蹤分支
在跟蹤分支里輸入 git push,Git 會自行推斷應該向哪個服務器的哪個分支推送數據。
$ git push



查看遠程倉庫信息
可以通過命令 git remote show [remote-name] 查看某個遠程倉庫的詳細信息,比如要看所克隆的 origin 倉庫
$ git remote show origin
它告訴我們
運行 git push 時缺省推送的分支是什么Local branch pushed with 'git push'
哪些遠端分支還沒有同步到本地New remote branches (next fetch will store in remotes/origin)
哪些已同步到本地的遠端分支在遠端服務器上已被刪除Stale tracking branches (use 'git remote prune')
運行git pull 時將自動合并哪些分支Remote branch merged with 'git pull' while on branch master
運行 git push 時缺省推送的分支是什么Local branch pushed with 'git push'
遠程倉庫的刪除和重命名
可以用 git remote rename 命令修改某個遠程倉庫在本地的簡短名稱
$ git remote rename pb paul
移除對應的遠端倉庫
$ git remote rm paul


分支
可以在不同分支里反復切換,并在時機成熟時把它們合并到一起。而所有這些工作,僅僅需要branch 和 checkout 這兩條命令就可以完成。
因為每次提交時都記錄了祖先信息(譯注:即parent 對象),將來要合并分支時,尋找恰當的合并基礎(譯注:即共同祖先)的工作其實已經自然而然地擺在那里了,所以實現起來非常容易。
新建一個 testing 分支
$ git branch testing
切換到其他分支,可以執行 git checkout命令(切換分支的時候最好保持一個清潔的工作區域。)
$ git checkout testing
切換回主分支
$ git checkout master
把 HEAD 指針移回到 master 分支,并把工作目錄中的文件換成了 master 分支所指向的快照內容。
Git 會把工作目錄的內容恢復為檢出某分支時它所指向的那個提交對象的快照。它會自動添加、刪除和修改文件以確保目錄的內容和你當時提交時完全一樣。
根據本分支新建并切換到該分支,運行git checkout 并加上 -b 參數:
$ git checkout -b iss53
根據對應分支新建并切換到該分支,(origin/serverfix對應分支的名稱,也可為遠程分支)
$ git checkout -b serverfix origin/serverfix
刪除已合并的分支
$ git branch -d hotfix
刪除尚未合并的分支(強制刪除)
$ git branch -d testing


分支的管理
給出當前所有分支的清單
$ git branch
查看各個分支最后一個提交對象的信息
$ git branch -v
要從該清單中篩選出你已經(或尚未)與當前分支合并的分支,可以用 --merge 和 --no-merged 選項
查看哪些分支已被并入當前分支(譯注:也就是說哪些分支是當前分支的直接上游。)
$ git branch --merged
列表中沒有 * 的分支通常都可以用 git branch -d 來刪掉。原因很簡單,既然已經把它們所包含的工作整合到了其他分支,刪掉也不會損失什么。
查看尚未合并的工作
$ git branch --no-merged
由于這些分支中還包含著尚未合并進來的工作成果,所以簡單地用 git branch -d 刪除該分支會提示錯誤,因為那樣做會丟失數據


合并
快進(Fast forward):直接祖先(需要合并的分支是需要被合并分支的直接祖先),如果順著一個分支走下去可以到達另一個分支的話,那么 Git 在合并兩者時,只會簡單地把指針右移。
非直接祖先:需要合并的分支和需要被合并分支分別在兩條分支上,Git 會用兩個分支的末端以及它們的共同祖先進行一次簡單的三方合并計算。對三方合并后的結果重新做一個新的快照,并自動創建一個指向它的提交對象,它有兩個祖先分別指向兩條分支。
$ git checkout master
$ git merge iss53
遇到沖突時的分支合并:如果在不同的分支中都修改了同一個文件的同一部分,Git 就無法干凈地把兩者合到一起
$ git merge iss53
$ git status
Git 作了合并,但沒有提交,它會停下來等你解決沖突。要看看哪些文件在合并時發生沖突,可以用 git status 查閱:
任何包含未解決沖突的文件都會以未合并(unmerged)的狀態列出。
Git 會在有沖突的文件里加入標準的沖突解決標記,可以通過它們來手工定位并解決這些沖突。
解決沖突的辦法無非是二者選其一或者由你親自整合到一起。
在解決了所有文件里的所有沖突后,運行 git add 將把它們標記為已解決狀態(譯注:實際上就是來一次快照保存到暫存區域。)。因為一旦暫存,就表示沖突已經解決。
認所有沖突都已解決,也就是進入了暫存區,就可以用 git commit 來完成這次合并提交。
合并遠程倉庫(遠程倉庫名/分支名)
$ git merge origin/serverfix


分支的新建與合并
實際工作中大體也會用到這樣的工作流程:1. 開發某個網站。 2. 為實現某個新的需求,創建一個分支。 3. 在這個分支上開展工作。
假設此時,你突然接到一個電話說有個很嚴重的問題需要緊急修補,那么可以按照下面的方式處理:

  1. 返回到原先已經發布到生產服務器上的分支。
  2. 為這次緊急修補建立一個新分支,并在其中修復問題。
  3. 通過測試后,回到生產服務器所在的分支,將修補分支合并進來,然后再推送到生產服務器上。
  4. 切換到之前實現新需求的分支,繼續工作。
    (注)當你在使用分支及合并的時候,一切都是在你自己的 Git 倉庫中進行的 — 完全不涉及與服務器的交互。

    利用分支進行開發的工作流程(典型的工作模式)
    長期分支,工作流水線(經過測試的提交對象集合被遴選到更穩定的流水線)
    這么做的目的是擁有不同層次的穩定性:當這些分支進入到更穩定的水平時,再把它們合并到更高層分支中去。
    master:僅在 master 分支中保留完全穩定的代碼,即已經發布或即將發布的代碼。
    develop(next):有一個名為 develop 或 next 的平行分支,專門用于后續的開發,或僅用于穩定性測試 — 當然并不是說一定要絕對穩定,不過一旦進入某種穩定狀態,便可以把它合并到 master 里。
    在確保這些已完成的特性分支(短期分支)能夠通過所有測試,并且不會引入更多錯誤之后,就可以并到主干分支中,等待下一次的發布。
    topic:指一個短期的,用來實現單一特性或與其相關工作的分支。
    在提交了若干更新后,把它們合并到主干分支,然后刪除。
     
    遠程分支
    是對遠程倉庫中的分支的索引。它們是一些無法移動的本地分支;只有在 Git 進行網絡交互時才會更新。遠程分支就像是書簽,提醒著你上次連接遠程倉庫時上面各分支的位置。
    我們用 (遠程倉庫名)/(分支名) 這樣的形式表示遠程分支。
    比如我們想看看上次同 origin 倉庫通訊時 master 分支的樣子,就應該查看 origin/master 分支。
    同步遠程服務器上的數據到本地。
    $ git fetch origin
    該命令首先找到 origin 是哪個服務器,從上面獲取你尚未擁有的數據,更新你本地的數據庫,然后把 origin/master 的指針移到它最新的位置上.

    推送本地分支到遠程分支
    要想和其他人分享某個本地分支,你需要把它推送到一個你擁有寫權限的遠程倉庫。
    你創建的本地分支不會因為你的寫入操作而被自動同步到你引入的遠程服務器上,你需要明確地執行推送分支的操作。
    對于無意分享的分支,你盡管保留為私人分支好了,而只推送那些協同工作要用到的特性分支。
    運行 git push (遠程倉庫名) (分支名):
    $ git push origin serverfix
    取出我在本地的 serverfix 分支,推送到遠程倉庫的 serverfix 分支中去
    $ git push [遠程名] [本地分支]:[遠程分支]
    $ git push origin serverfix:serverfix
    上傳我本地的 serverfix 分支到遠程倉庫中去,仍舊稱它為 serverfix 分支
    $ git push origin serverfix:awesomebranch
    通過此語法,你可以把本地分支推送到某個命名不同的遠程分支


    跟蹤遠程分支
    從遠程分支 checkout 出來的本地分支,稱為 跟蹤分支,跟蹤分支是一種和某個遠程分支有直接聯系的本地分支。
    在跟蹤分支里輸入 git push,Git 會自行推斷應該向哪個服務器的哪個分支推送數據。
    在這些分支里運行 git pull 會獲取所有遠程索引,并把它們的數據都合并到本地分支中來。
    Git 通常會自動創建一個名為 master 的分支來跟蹤 origin/master。這正是 git push 和 git pull 一開始就能正常工作的原因。
    跟蹤分支
    $ git checkout -b [分支名] [遠程名]/[分支名]
    $ git checkout --track origin/serverfix
    為本地分支設定不同于遠程分支的名字
    $ git checkout -b sf origin/serverfix
    你的本地分支 sf 會自動將推送和抓取數據的位置定位到 origin/serverfix 了。

    刪除遠程分支
    在服務器上刪除 serverfix 分支
    $ git push [遠程名] :[分支名]
    $ git push origin :serverfix

    分支的衍合
    用衍合的目的:比如某些項目你不是維護者,但想幫點忙的話,最好用衍合:先在自己的一個分支里進行開發,當準備向主項目提交補丁的時候,根據最新的 origin/master 進行一次衍合操作然后再提交,這樣維護者就不需要做任何整合工作(如果是merge的話)
    衍合的分支還是跟在master后面,不會創建新的分支,而且已經merge到了主分支后面(已經整合好了),所以維護者觀看后可以直接merge主分支,或者拋棄這次衍合。
    而如果是使用merge的話,你提交的另一個分支,維護者還需要merge到主分支,然后刪除這個分支。
    實際上是把解決分支補丁同最新主干代碼之間沖突的責任,化轉為由提交補丁的人來解決。只需根據你提供的倉庫地址作一次快進合并,或者直接采納你提交的補丁。
    有了 rebase 命令,就可以把在一個分支里提交的改變移到另一個分支里重放一遍。
    $ git checkout experiment
    $ git rebase master
    衍合也可以放到其他分支進行,并不一定非得根據分化之前的分支。但這需要用 git rebase 的 --onto 選項指定新的基底分支 master:
    $ git rebase --onto master server client
    取出 client 分支,找出 client 分支和 server 分支的共同祖先之后的變化,然后把它們在 master 上重演一遍
    先取出特性分支 server,然后在主分支 master 上重演
    git rebase [主分支] [特性分支]
    $ git rebase master server
    使用 衍合的原則:
    一旦分支中的提交對象發布到公共倉庫,就千萬不要對該分支進行衍合操作。
    如果把衍合當成一種在推送之前清理提交歷史的手段,而且僅僅衍合那些尚未公開的提交對象,就沒問題。
    如果衍合那些已經公開的提交對象,并且已經有人基于這些提交對象開展了后續開發工作的話,就會出現叫人沮喪的麻煩。




    專業詞匯意思:
    checkout:Checkout a branch or paths to the working tree(切換到其他分支)
    Trunk:軟件開發過程中的主線,開發時版本存放的目錄,即在開發階段的代碼都提交到該目錄上,保存了從版本庫建立到當前的信息。
    Branches:軟件開發過程中的分支,發布版本存放的目錄,即項目上線時發布的穩定版本存放在該目錄中,保存了從版本庫的某一特定點(不一定是版本庫建立時)到當前的信息。
    分支主要用于在不影響Trunk其它用戶情況下進行一些關于新功能的探索性或實驗性的開發,待新功能完善后它也可以合并到Trunk中。
    Tags
    stage
    rebase:衍合
    commit:已暫存的文件,staged的文件,下次提交會一并記錄到倉庫。
    committed:表示該文件已經被安全地保存在本地數據庫中了, Git 目錄中保存著的特定版本文件,就屬于已提交狀態。
    modified:已修改表示修改了某個文件,但還沒有提交保存,如果自上次取出后,作了修改但還沒有放到暫存區域,就 是已修改狀態。
    staged:已暫存表示把已修改的文件放在下次提交時要保存的清單中,如果作了修改并已放入暫存區域,就屬于已暫存狀態;
    working directory:Git 的工作目錄,從 Git 目錄中取出某個版本的所有文件和目錄,用以開始后續工作的叫做工作目錄。接下來就可以在工作目錄中對這些文件進行編輯。
    staging area:暫存區域,暫存區域只不過是個簡單的文件(索引文件),一般都放在 Git 目錄中。
    git directory(repository,Git 目錄):本地倉庫,該目錄非常重要,每次克隆鏡像倉庫的時候,實際拷貝的就是這個目錄里面的數據。
    git clone 出來的話,就是其中 .git 的目錄;如果git clone --bare 的話,新建的目錄本身就是 Git 目錄。它是 Git 用來保存元數據和對象數據庫的地方。
    Git 工作流程:1. 在工作目錄中修改某些文件。 2. 對修改后的文件進行快照,然后保存到暫存區域。 3. 提交更新,將保存在暫存區域的文件快照永久轉儲到 Git 目錄中。
    本地版本控制系統:諸如 rcs
    集中化的版本控制系統,簡稱 CVCS:諸如 CVS,Subversion 以及 Perforce 等。可以在一定程度上看到項目中的其他人正在做些什么。而管理員也可以輕松掌控每個開發者的權限,并且管理一個 CVCS 要遠比在各個客戶端上維護本地數據庫來得輕松容易。
    分布式版本控制系統,簡稱 DVCS:像 Git,Mercurial,Bazaar 以及 Darcs 等.客戶端并不只提取最新版本的文件快照,而是把原始的代碼倉庫完整地鏡像下來。這么一來,任何一處協同工作用的服務器發生故障,事后都可以用任何一個鏡 像出來的本地倉庫恢復。因為每一次的提取操作,實際上都是一次對代碼倉庫的完整備份(見圖 1-3)。
    merge:Join two or more development histories together
    pull:Fetch from and merge with another repository or a local branch
    push:Update remote refs along with associated objects
    tracking branch:從遠程分支 checkout 出來的本地分支,稱為 跟蹤分支
    Pull Request:在派生項目中創建的提交,可以非常方便地利用GitHub的Pull Request工具向原始項目的維護者發送Pull Request。

    獲取幫助:git help or git help config or git --help or man git-
    glob 模式:所謂的 glob 模式是指 shell 所使用的簡化了的正則表達式。星號(*)匹配零個或多個任意字符;[abc] 匹配任何一個列在方括號中的字符(這個例子要么匹配一個 a,要么匹配一個 b,要么匹配一個 c);問號(?)只匹配一個任意字符;如果在方括號中使用短劃線分隔兩個字符,表示所有在這兩個字符范圍內的都可以匹配(比如[0-9] 表示匹配所有 0 到 9 的數字)。

    --pretty=format常用的格式占位符寫法及其代表的意義
    選項   說明
    %H  提交對象(commit)的完整哈希字串
    %h  提交對象的簡短哈希字串
    %T  樹對象(tree)的完整哈希字串
    %t  樹對象的簡短哈希字串
    %P  父對象(parent)的完整哈希字串
    %p  父對象的簡短哈希字串
    %an 作者(author)的名字
    %ae 作者的電子郵件地址
    %ad 作者修訂日期(可以用 -date= 選項定制格式)
    %ar 作者修訂日期,按多久以前的方式顯示
    %cn 提交者(committer)的名字
    %ce 提交者的電子郵件地址
    %cd 提交日期
    %cr 提交日期,按多久以前的方式顯示
    %s  提交說明




    idea
    綠色:staged 提交后新增加的文件,并且加入了跟蹤,但未提交,已暫存狀態,如果此時提交,那么該文件此時此刻的版本將被留存在歷史記錄中
    紅色:未被跟蹤的文件,提交后增加新文件而未加入跟蹤untracked
    藍色:已經修改的文件,modified
    灰色:未被修改的文件
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!