歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Git進階教程

Git進階教程

日期:2017/2/28 13:59:13   编辑:Linux教程

今天無意中看到據說是Git入門教程 http://www.linuxidc.com/Linux/2014-09/107300.htm,看完後又學到了不少新東西,把自己學到東西總結並記錄下,否則總覺得少了些什麼東西。

下面用一張圖來說明工作區(working directory)、版本庫(Repository)、暫存區(stage),以及分支的概念。

下面解釋不是完全嚴謹,請結合上圖來理解下面四個概念。
工作區(working dicrectory):包含.git目錄的父目錄一般就是工作區,就是我們的工程目錄。新創建的文件都處於工作區,此時還沒有加入到後面要解釋的的暫緩區。

版本庫(Repository):.git目錄就是版本庫,版本管理的相關文件都在此目錄下。

暫緩區(stage):對於曾經加入了版本控制的文件作了修改後,執行git add後的文件就進入暫緩區。

分支:git初始會默認創建一個master分支,執行git commit後,暫緩區的文件就到了分支裡面。

如下有一個readme.rst文件是已經加入了版本庫的,現在對內容進行修改後,查看下狀態

E:\Users\liuzhijun\workspace\blog>git status

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.
#   (use "git push" to publish your local commits)
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working d
#
#       modified:   README.rst
#
no changes added to commit (use "git add" and/or "git commit -a")

git提示README.rst已經修改了,但還不是暫緩區的文件(not staged),待commit。接著還告訴你可以進行怎麼的操作,checkout指撤銷本次修改,注意後面有--,如果不帶這個字符,checkout又是另外一層意思了。

退回到指定版本

退回到指定版本使用命令git reset --hard <version>, HEAD始終指向當前版本,HEAD^^表示上一個版本。如果想退回到上一個版本就可以使用:

git reset --hard HEAD^^  

如果想退回到指定的某個版本呢?可以使用git log查看獲取commit 版本號:

commit 33b351ae746edaf3fd5a56a0318235096b6ed1ce
Author: liuzhijun <[email protected]>
Date:   Sat Mar 15 11:43:56 2014 +0800
    commit many files

commit 86eefaaea5251fa5707ecd02009c893c098ab6cd
Author: liuzhijun <[email protected]>
Date:   Thu Mar 14 03:20:27 2013 +0800

    add author myself

commit 後面的那串就是版本號, 一般只要選擇前面幾位就可以了。git會自動去查找。

git reset --hard 86eefa

執行上面的命令就是退回到指定的版本,如果現在我又反悔了,想恢復到最近的那個版本怎麼辦?只要你還記得這個最近的版本號的話直接執行如上的命令就好了,但是誰會去記這個號啊?那麼還有一個辦法是使用git reflog查看,這個指令記錄了每次的操作。

E:\Users\liuzhijun\workspace\blog>git reflog
a11c917 HEAD@{0}: reset: moving to a11c
        HEAD@{1}: reset: moving to HEAD^
        HEAD@{2}: reset: moving to a11c917430050a94549e48d205ef01cacc82c1cf
        HEAD@{3}: reset: moving to HEAD^

上面的allc...就是我最近的一次修改。

修改(change)

這裡的修改不是動詞,而是名詞,只要文件發生了變化就表示修改,包括對文件內容的更改或者新創建的一個文件或者刪除一個文件都叫一個修改。 git跟蹤(track)的就是修改,而不是文件本身。

撤銷(checkout)

撤銷是指文件修改後,還沒有添加到暫緩區(還沒有執行git add)過程中的修改撤銷掉,如果已經添加到了暫緩區,但是還沒有commit到分支中去,又做了修改後又想撤銷,那麼這裡的撤銷就是撤銷到暫緩區的狀態。比如現在對文件添加內容"add some to file":

E:\Users\liuzhijun\workspace\blog>git status
# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.
#   (use "git push" to publish your local commits)
#
# 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:   README.rst

然後把它添加到暫緩區:

git add README.rst

再添加內容 "add some again to file",撤銷後,你會發現第一次添加的內容保留了,第二次添加的內容撤銷了。

E:\Users\liuzhijun\workspace\blog>git checkout -- README.rst

E:\Users\liuzhijun\workspace\blog>git status
# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.
#   (use "git push" to publish your local commits)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   README.rst

分支管理

開發一個新功能時,可能需要幾周的時間才能完成,那麼可以創建一個分支,在分支上做開發,而不影響主分支的功能。
創建分支

git branch dev
git checkout dev

或者合並成一條命令:

git checkout -b dev

創建dev分支切換後,HEAD指針就從原來的master轉移指向dev分支,git branch可以查看有哪些分支,並且當前是在哪個分支上。

E:\Users\liuzhijun\workspace\blog>git branch
* dev
  master

星號就代表當前的所在的分支。

切換分支

git checkout master

合並分支
切換分支後,dev分支上做的修改在master分支看不到,如果dev分支的功能開發完成後,就可以考慮合並分支了,合並後還可以刪除dev分支,因為此時dev分支對於我們來說沒有多大意義了。

git merge dev

合並分支就是把master執行dev分支,接著還可以刪除分支

git branch -d dev

git鼓勵大家使用分支,因此大家記得多用啊,只有多用才是熟練掌握。

沖突

如果不同的人對同一個文件的同一個地方做了修改,那麼提交後就會遇到沖突,或者在不同的分支上修改了同一個文件的同一個地方也會出現沖突,當出現沖突了,就必須手動把有沖突的地方修改後再提交才能解決沖突。

創建分支dev,然後添加內容"add new branch dev",commit後切換到master分支,在同一行添加內容"may be here is conflict",commit後合並。

git checkout -b dev
git add README.rst
git commit -m "add new branch"
git checkout master
git add README.rst
git commit -m "add new line"
git merge dev

#出現錯誤
Auto-merging README.rst
CONFLICT (content): Merge conflict in README.rst
Automatic merge failed; fix conflicts and then commit the result.

README.rst內容出現了如下情況:

<<<<<<< HEAD
may be here is conflict
=======
add new branch dev 
>>>>>>> dev

<<<<<<< 到=======\表示當前分支的內容, >>>>>表示dev裡面的內容。手動修改裡面的內容後再提交。那麼master就是最新的文件了。當然dev還是停留在上次commit的狀態。此時你可能會想,我想在dev分支上與master保持同樣的最新狀態,那麼你可以這樣:

git checkout dev
git rebase master

相當於快速的把dev分支指向master。

分支策略

開發過程中,都應該按照以下方式來管理分支。
主分支:代碼庫應該有且只有一個主分支master,master分支的代碼是穩定的,僅用於正式版本發布使用。

開發分支:日常開發工作應該在開發分支dev上完成,待某個時間dev分支的功能完善了就可以考慮merge到master分支上去。

自己的分支:每個人在dev分支上建立自己的分支。
默認情況下,git合並使用"fast forward”模式,相當於直接把master分支指向dev分支。刪除分支後,分支信息也隨即丟失。

在合並的時候附上參數 --no-ff就可以禁用fast-forward合並模式。這樣在master上能生成一個新的節點,意味著master保留的分支信息,而這種合並方式我們希望采用的。

git merge --no-ff dev

Ubuntu完美安裝搭建Git服務器 http://www.linuxidc.com/Linux/2015-07/120616.htm

GitHub 教程系列文章

GitHub 使用教程圖文詳解 http://www.linuxidc.com/Linux/2014-09/106230.htm

Git 標簽管理詳解 http://www.linuxidc.com/Linux/2014-09/106231.htm

Git 分支管理詳解 http://www.linuxidc.com/Linux/2014-09/106232.htm

Git 遠程倉庫詳解 http://www.linuxidc.com/Linux/2014-09/106233.htm

Git 本地倉庫(Repository)詳解 http://www.linuxidc.com/Linux/2014-09/106234.htm

Git 服務器搭建與客戶端安裝 http://www.linuxidc.com/Linux/2014-05/101830.htm

Git 概述 http://www.linuxidc.com/Linux/2014-05/101829.htm

分享實用的GitHub 使用教程 http://www.linuxidc.com/Linux/2014-04/100556.htm

Ubuntu下Git服務器的搭建與使用指南 http://www.linuxidc.com/Linux/2015-07/120617.htm

Git 的詳細介紹:請點這裡
Git 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved