Git學習記錄

學習Git的動機

  • 最近在作畢業設計,寫了一個APP。寫完以後各類調試,把代碼刪了改、改了刪,不少重複的勞動。尤爲是當你修改了代碼,發現整個程序崩了,你想要還原成原來能夠運行的代碼,卻又不記得刪了什麼東西的時候,絕對是十分使人抓狂的。所以在把這個畢設搞完以後,我決心要好好研究一下Git以及Github,把版本控制這個問題好好地解決掉。

Git是啥(做用)

  • Git,官方的解釋我就不說了,網上一大堆,我說說個人理解吧。
  1. 最大的做用固然就是對文件每一次的修改進行記錄。每修改一次,至關於文件的一個版本。當修改被提交到倉庫(Repository)後,Git就會記錄下這一次的修改,並做爲文件的其中一個版本。當你須要將文件恢復到此次修改前的狀態(即放棄此次修改),則直接回退到上一個版本就行。
  2. 除了記錄每一次文件的修改,還能夠進行協同開發。當兩我的都須要修改代碼文件時,溝通成本會很高。所以Git能夠將代碼倉庫分紅幾個分支(branch),每個分支上均可以記錄對這個倉庫的每一次修改。每個人能夠在本身的分支上對文件進行修改、恢復、修改、恢復,你所在的分支會記錄下你修改的全部版本。你也無需關注別人對文件修改了什麼,只要最後將多我的的分支合併,就能夠實現多人對文件進行修改,也就是協同開發。

主要內容

由於這只是一篇學習記錄,所以我會簡單地介紹一下一些經常使用命令的使用,不會涉及到Git內部的原理、機制。對於Git的操做,主要是使用到git bash。若是讀者尚未安裝Git的話,能夠上網找其餘博客學習如何安裝。git

1 建立代碼版本倉庫(Repository)

git bash有點像Linux下的命令行,它會擁有當前工做目錄。所以首先,要將當前目錄設爲你的目標目錄。默認的工做目錄是:C:/用戶/Administrator(你的用戶名)。進入到目標目錄後,使用git init命令來建立版本庫。github

建立成功

2 將文件添加進版本庫中

接着,就是將文件添加進版本庫中。首先要在當前目錄下建立一個文本文件readme.txt,並在文件中寫入相應的內容(也就是對文件進行修改)。修改完後,使用git add <file>添加文件(<file>替換爲文件名),使用git commit -m <message>將添加後的文件提交至版本庫中(<message>替換爲此版本的備註信息),做爲一個修改版本。其中可使用屢次git add添加多個文件,而後使用一次git commit將多個文件添加進版本庫中。bash

添加成功

3 版本回退

修改了文件以後,若是想要將文件恢復到修改前的版本,該咋辦?這時就須要使用到命令git reset --hard commit_id或者是git reset --hard HEAD^,其中HEAD^是回退到上一個版本,HEAD^^是回退到上上個版本……。至於commit_id,由於Git對每一次版本的提交,都會分配一個提交版本號(版本號),即commit_id。所以咱們能夠經過指定版本號來將文件回退至指定的版本。至於版本號,咱們能夠經過命令git log來查看提交記錄,就能夠從提交記錄中查看到版本號。app

在文件中添加新的一行內容

使用git log命令查看提交記錄

從上圖中咱們能夠看出,上一個提交版本的版本號爲60084e……。實際上在使用命令時,不須要將版本號一字不漏地敲出來,只須要敲前面幾個字符,讓系統可以識別出是哪一次提交就能夠了。學習

回退成功

從上圖中能夠看出,readme.txt文件已經恢復到修改前的狀態,說明回退成功。然而,我想了想,發現原來的代碼並無錯,我須要回到剛纔恢復前的狀態,咋辦?依然是使用命令git reset --hard commit_id來實現。然而,使用git log並不能看到將來的版本號(即回退前的版本號),這時就須要使用命令git reflog來查看將來幾個版本的版本號。spa

查看回退前的版本號

經過命令git reflog咱們能夠看到回退前的版本號爲0ebce……,這時就可使用使用命令git reset --hard commit_id使文件恢復到回退前的版本。命令行

恢復成功

4 建立與合併分支

4.1合併分支無衝突

前面的操做都是在默認的主分支master下進行的,可是若是是多人修改文件的話,就須要建立多個子分支,每個分支至關因而一條版本線,最終能夠經過分支合併將多個修改後的版本合成最終的版本。
建立分支主要是經過命令git branch <name>實現,切換分支是經過git checkout <name>實現,其中<name>替換爲分支名。這兩個步驟也能夠合起來,使用一條命令git checkout -b <name>來實現。可使用git branch來查看版本庫現有的分支。設計

新建並切換分支

切換了分支以後,就能夠在這個分支上對文件進行修改,子分支上的修改並不會影響到主分支。不管在子分支上如何修改文件,主分支上的文件都不會受到影響。在子分支上修改完文件後,能夠將子分支與主分支合併,使得子分支上修改的文件與主分支上的文件合併。例如,我在子分支dev上對文件進行修改,添加新的一行,並提交至版本庫的子分支dev上:版本控制

修改文件,並將結果提交至分支上

這時再使用命令git checkout master切換回主分支,查看主分支上readme.txt文件的內容:調試

主分支上的文件

能夠看到,master分支上的文件沒有剛纔添加的"add dev new line",這就說明dev分支上對文件進行修改,並不會影響到master分支上的文件。
在dev分支上修改完文件後,須要將最終的結果合併到master分支上。可使用命令git merge <name>來實現。也可使用命令git branch -d <name>來刪除分支。

將dev分支合併至master分支,並刪除dev分支

從文件的輸出結果能夠看出,將dev分支合併至master分支後,master分支上的文件已經接受了dev分支上對於文件的修改操做,合併成功。最終將dev分支進行刪除。在平時的開發中,master分支應該是用來保存最終須要發佈的代碼的正式版本,而dev分支則是用來保存開發、修改的代碼的調試版本。不管在dev分支上如何修改代碼,都不會影響到master分支上的正式版代碼。

4.2合併分支有衝突

什麼叫合併分支有衝突?就是兩條分支都修改過文件,在分支合併時就會出現矛盾,Git不知道文件應該怎麼合併,這時Git就會提示用戶分支衝突。分支衝突以後就須要用戶手動進行合併,而後將合併後的文件從新添加、提交至版本庫中。

合併衝突

手動合併後再從新提交

4.3保存分支的歷史記錄(git merge –no-ff)

在使用git merge將子分支與主分支合併後,Git默認使用的是Fast forward模式進行分支合併,這時版本庫中不會保存子分支的歷史版本信息,以下圖的右邊所示。若刪除子分支後,咱們想查看子分支的歷史版本信息則會失敗。此外,我在其餘博客中還看到說,主分支通常都是發佈正式版本的程序,若使用右邊的這種合併方式,則會將子分支中的版本信息混入到主分支中,至關於將主分支的歷史版本信息弄「渾濁」了,這顯然不是咱們想要的結果。這是就須要使用命令git merge –no-ff禁用Fast forward模式進行分支合併,從而達到下圖左邊的這種效果。子分支刪除後,依然能夠看到子分支的歷史版本信息。合併後會在主分支上提交一個新的版本,這是主分支與子分支合併後的新版本。

兩種合併方式的區別

總結廖雪峯老師的Git教程中出現的命令

初始化Git倉庫

$ git init

添加文件到Git倉庫

// 可屢次添加文件後再提交
$ git add <file> 
$ git commit -m <message>

查看工做區的狀態

$ git status

查看修改內容(工做區與暫存區的區別)

$ git diff

回退至任意版本

$ git reset --hard commit_id

查看提交歷史

$ git log

查看命令歷史(能夠查看將來(回退前)提交版本)

$ git reflog

當你改亂了工做區某個文件的內容,想直接丟棄工做區的修改時

$ git checkout -- <file>

當你不但改亂了工做區某個文件的內容,還添加到了暫存區時,想丟棄修改

此場景下分爲兩步:
先使用命令git reset HEAD <file>回到上一種狀況,而後再用解決上一種狀況的命令解決。

工做區、暫存區、版本庫

刪除文件(本地與版本庫中的文件均刪除)

本地的文件直接刪除便可。
刪除版本庫中的文件須要如下的命令:

// 即先刪除後提交
$ git rm test.txt
$ $ git commit -m "remove test.txt"

本地文件誤刪了,須要從版本庫中將文件恢復至本地(前提是本地文件已提交至版本庫中)

$ git checkout -- test.txt

將本地Git倉庫與遠程代碼庫鏈接(Github代碼庫)

$ git remote add origin git@github.com:zhuangbility111/learngit.git

zhuangbility111這個替換爲本身的Github帳戶名

第一次推送master分支的全部內容至遠程庫

$ git push -u origin master

之後每一次推送最新修改至遠程庫

$ git push origin master

從遠程庫中克隆(下載)代碼庫至本地代碼庫(版本庫)中

$ git clone git@github.com:zhuangbility111/gitskills.git

與分支相關的命令

// 查看現有分支
$ git branch

// 建立分支
$ git branch <name>

// 切換分支
$ git checkout <name>

// 建立+切換分支
$ git checkout -b <name>

// 合併某分支至當前分支
$ git merge <name>

// 刪除分支
$ git branch -d <name> 

// 查看分支合併圖
$ git log --graph

// 禁用Fast forward模式進行合併分支(能夠查看子分支的歷史記錄)
$ git merge --no-ff -m <message> dev

保存工做現場,以及恢復工做現場(未提交至版本庫中)

// 在未提交至版本庫的狀況下暫時保存工做現場,切換至其餘分支
$ git stash
// 恢復工做現場
$ git stash pop

丟棄一個沒有合併過的分支(強行刪除)

$ git branch -D <name>

查看遠程庫(Github代碼庫)信息

$ git remote -v

從本地推送分支至遠程庫

// 在本地建立和遠程分支對應的分支,`origin/branch-name`爲遠程庫的分支名
$ git checkout -b branch-name origin/branch-name

// 從本地推送分支至遠程庫
$ git push origin branch-name

// 若是推送失敗,則先須要將遠程庫中的分支讀取至本地庫,與本地庫中對應的分支進行合併
// 若是在將遠程庫的分支與本地分支合併的過程當中出現衝突,則解決合併衝突,提交至本地庫,而後推送至遠程庫
$ git pull

// 若是git pull提示no tracking information,則說明本地分支和遠程分支的連接關係沒有建立
// 創建本地分支和遠程分支的關聯
$ git branch --set-upstream-to <branch-name> origin/<branch-name>

查看歷史提交的commit id

$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file

給提交打標籤,新建標籤(至關於給提交換個別名,而不是使用commit id)

// 查看全部標籤
$ git tag

// 默認給當前分支的最新提交設定標籤,這個也能夠經過commit id來指定給哪個提交打標籤
$ git tag <tagname>
$ git tag v0.9 f52c633

// 建立帶有說明的標籤,用-a指定標籤名,-m指定說明文字
$ git tag -a <tagname> -m "blablabla..."
$ git tag -a v0.1 -m "version 0.1 released" 1094adb

// 查看標籤說明文字
$ git show <tagname>
$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 22:48:43 2018 +0800

version 0.1 released

commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:06:15 2018 +0800

    append GPL

diff --git a/readme.txt b/readme.txt
...

操做標籤

// 刪除標籤
$ git tag -d v0.1

// 推送本地庫的某個標籤至遠程庫
$ git push origin <tagname>

// 推送所有未推送過的本地標籤至遠程庫
$ git push origin --tags

// 刪除本地標籤(與第一個相同)
$ git tag -d <tagname>

// 刪除遠程標籤
$ git push origin :refs/tags/<tagname>

寫在最後

在今天看完廖雪峯老師的教程後,我很興奮,因而就急匆匆地寫下了這篇博客,權當是一篇學習筆記吧。Git真的是可以幫助我在實際的開發中提升效率的東西。固然,由於我只是剛接觸Git,因此此篇博客的內容較簡單,都是一些經常使用的操做。還有些我暫時不太理解有什麼用處,或者對我來講暫時用處不大的內容,我都沒有提到。等我詳細地瞭解了Git的使用方法,而且熟練使用Git後,我會再繼續撰寫與Git相關的文章。

相關文章
相關標籤/搜索