經常用到的git操作,簡單易懂演示一波

reahink發表於2019-03-11

雖然現在編輯器或者各種git擴充套件很好用,並極大的提高了生產力。但是也出現了一些現象:一些工程師對諸如webstorm或者vscode之類的視覺化git操作用得心應手,但對一些其中的git命令的意思卻不求甚解。對,說的就是我以前的我。

而且還有個現象,一旦你依賴於編輯器的視覺化操作,那麼對命令列的操作會出現恐懼的心理,我以前是這樣。所以為了改變現狀,現在徹底告別視覺化操作,擁抱命令列。

說到git的一些操作,常用的諸如:

$ git clone
$ git branch
$ git checkout 分支名
$ git checkout -b 分支名
$ git checkout origin/<遠端分支> -b <本地分支>
$ git add
$ git checkout -- <file>
$ git reset
$ git commit
$ git push
$ git fetch  #並沒更改本地倉庫的程式碼,只是拉取了遠端commit資料,將遠端倉庫的commit版本號 更新為最新。分支git log資訊不會變
$ git pull  #fetch+merge,把遠端程式碼拉到本地並merge,git log資訊會更新
$ git merge
$ git rebase
$ git log
$ git rebase -i <提交版本號>
$ git log master..dev  #檢視 dev 中比 master 中多提交了哪些內容
複製程式碼

比如下面我要開發新專案,新專案已經在遠端倉庫了

  • 首先我拉專案到本地
$ git clone <遠端倉庫地址>

# 通常拉下來的是預設分支master,那麼想要拉下的是另一個分支的程式碼的話
$ git clone -b <分支名> <遠端倉庫地址>
複製程式碼
  • 開發階段,首先要從master上切出一個開發分支
$ git checkout -b <分支名>

# 我給開發分支起名叫:dev
$ git checkout -b dev
Switched to a new branch 'dev'
複製程式碼
  • 如果有個同事已經有了個開發分支,讓我直接用他的開發分支開發功能
# 使用
$ git checkout origin/<遠端分支> -b <本地分支>

# 他的分支叫:dev1
$ git checkout origin/dev1 -b dev1
複製程式碼
  • 此時我想看下本地和遠端分別有哪些分支
# 檢視本地分支列表,*號所在的那個是當前分支
$ git branch
  dev
* dev1
  master
  
# 檢視遠端分支列表,列印出的列表,紅顏色的代表遠端分支
$ git branch -a

複製程式碼
  • 我新增了一個“git-test.js”檔案、改了一個"index.html"檔案
# 輸入git status檢視狀態
$ git status
On branch dev1
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:   index.html

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        git-test.js

no changes added to commit (use "git add" and/or "git commit -a")

# 列印出的資訊表示,index.html 檔案<修改的部分>還未新增到git暫存區。
# Untracked files表示:新增的 git-test.js 檔案還未被跟蹤
複製程式碼
  • 我想了一下,決定不對 index.html 做更改了,想一下子把它返回到未更改狀態
$ git checkout -- index.html

# 如果想將多個檔案撤銷呢,檔名用一個“.”代替
$ git checkout -- .
複製程式碼
  • 現在我將未跟蹤的 git-test.js 檔案加到git 暫存區
# 此處的“.”,和上面的“.”作用一樣,代表多個檔案
$ git add .

# 現在檢視下狀態
$ git status
On branch dev1
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
        new file: git-test.js

# 然後我又想將剛加到暫存區的git-test.js移出暫存區(我是不是傻)
$ git reset HEAD git-test.js
$ git status
On branch dev1
Untracked files:
  (use "git add <file>..." to include in what will be committed)
		git-test.js
複製程式碼
  • 現在git-test.js又被加到了暫存區,並且要提交了
$ git commit -m "add git-test.js"
[dev1 5198153] add git-test.js
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 git-test.js
 
# 現在看下git log
$ git log
commit 51981532d54b62811d8afb9b2493cb3320752eae
Author: xxx <xx@xx.com>
Date:   Wed Jul 11 18:04:00 2018 +0800
    add git-test.js
複製程式碼
  • 此時我又對index.html檔案做了更改
# 將更改後的index.html加到暫存區
$ git add index.html

# 提交,但是我想將這次的提交和上次的提交合並
$ git commit --amend

# 列印出以下資訊,這是vim編輯視窗
add git-test.js
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Jul 11 18:04:00 2018 +0800
#
# On branch dev1
# Changes to be committed:
#       modified:   index.html
#       new file:   git-test.js
#
~
~

# 按shift+:,輸入q,退出編輯
[dev1 3da072a] add git-test.js
 Date: Wed Jul 11 18:04:00 2018 +0800
 2 files changed, 1 insertion(+)
 create mode 100644 git-test.js
複製程式碼

有時候我們提交了好幾個commit,但是想要回到某次的提交

# 回退到上一個版本
$ git reset --hard HEAD^

# 回退到往上 n 個版本
$ git reset --hard HEAD~n

# 回退到某個版本號的版本
$ git reset --hard <版本號>
複製程式碼

好了,開發一段時間了,今天要把master分支給合併過來

$ git merge master
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

# 列印出來的資訊說:修復衝突,然後提交結果

# 看下git狀態
$ git status
On branch dev1
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to xxx resolution)

        both modified:   index.html
        
# 修復衝突後
$ git add index.html
$ git commit -m "merge master"

$ git log
commit 3030e65c149442a26649fb5e6a2bdb89c976cbc8
Merge: 3da072a 78363ff
Author: zhangqinmiao <564777189@qq.com>
Date:   Wed Jul 11 18:47:27 2018 +0800

    merge master

commit 78363ff222bc847076bbc96e26f56b04b58ad19d
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:34:55 2018 +0800

    update index.html

commit 3da072aee0eacf7a8315c3ead1ead88bb0fcf3ed
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:04:00 2018 +0800

    add git-test.js

##########################################
# 如果在合併狀態下,不想合併分支了的話
$ git merge --abort
複製程式碼

有人說了,我合併用rebasbe呢,和merge有何不同

# 我們切到master分支,看下log
$ git checkout master
Switched to branch 'master'

$ git log
commit c5d5bd4046c6c8fb75addfad49e5c396f53f9da1
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:52:46 2018 +0800

    update 0711

commit 78363ff222bc847076bbc96e26f56b04b58ad19d
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:34:55 2018 +0800

    update index.html

commit 784f9f65951386344e5073652a88d70a2276f35e
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 11:21:13 2018 +0800

################################################
# 上面列印出的log,顯示是最近三次的master分支的提交

# 下面我們看下dev1分支的log
$ git checkout dev1
$ git log
commit 3da072aee0eacf7a8315c3ead1ead88bb0fcf3ed
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:04:00 2018 +0800

    add git-test.js
################################################    
    
# 當dev1分支rebase master分支後
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: add git-test.js

$ git log
commit b5e1b59c1adb19e6e49e937364f5d00b23942324
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:04:00 2018 +0800

    add git-test.js

commit c5d5bd4046c6c8fb75addfad49e5c396f53f9da1
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:52:46 2018 +0800

    update 0711

commit 78363ff222bc847076bbc96e26f56b04b58ad19d
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:34:55 2018 +0800

    update index.html
複製程式碼

注意: 雖然“update 0711”這次提交的時間比“add git-test.js”這次提交的時間晚,一個18:52:46,一個18:04:00。這是因為rebase master是以master分支作為基礎,然後合併就以master的提交記錄開始依序開始。詳細介紹

如果你想合併多個commit

# 看下本分支的log
$ git log
commit b5e1b59c1adb19e6e49e937364f5d00b23942324
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:04:00 2018 +0800

    add git-test.js

commit c5d5bd4046c6c8fb75addfad49e5c396f53f9da1
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:52:46 2018 +0800

    update 0711

commit 78363ff222bc847076bbc96e26f56b04b58ad19d
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:34:55 2018 +0800

    update index.html
    
複製程式碼
  • 複製“update index.html”這次提交的版本號,到下面的 -i 後面
$ git rebase -i 78363ff222bc847076bbc96e26f56b04b58ad19d
複製程式碼
  • 列印出以下vim編輯資訊
pick c5d5bd4 update 0711
pick b5e1b59 add git-test.js

# Rebase 78363ff..b5e1b59 onto 78363ff (2 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
複製程式碼

前兩行前面的pick,在Commands下面有解釋,如下我將前兩行改為以下形式:

pick c5d5bd4 update 0711
s b5e1b59 add git-test.js
複製程式碼

上面修改的意思是:使用b5e1b59這個的提交,但是合併到之前的提交。

  • 修改完成後,儲存。然後有列印出以下vim編輯資訊
# This is a combination of 2 commits.
# The first commit's message is:

update 0711

# This is the 2nd commit message:

add git-test.js

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Jul 11 18:52:46 2018 +0800
#
# interactive rebase in progress; onto 78363ff
# Last commands done (2 commands done):
#    pick c5d5bd4 update 0711
複製程式碼
  • 此時你可以修改資訊為以下形式
rebase -i test
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Jul 11 18:52:46 2018 +0800
#
# interactive rebase in progress; onto 78363ff
# Last commands done (2 commands done):
#    pick c5d5bd4 update 0711

複製程式碼
  • 儲存後,列印出以下資訊。提示成功
[detached HEAD 747712c] rebase -i test
 Date: Wed Jul 11 18:52:46 2018 +0800
 3 files changed, 218 insertions(+), 4 deletions(-)
 create mode 100644 git-test.js
Successfully rebased and updated refs/heads/dev1.

# 檢視下log
$ git log
commit 747712c3b99e734d85defcacdc0a1d4610c6d9af
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:52:46 2018 +0800

    rebase -i test

commit 78363ff222bc847076bbc96e26f56b04b58ad19d
Author: xxx <xxx@xx.com>
Date:   Wed Jul 11 18:34:55 2018 +0800

    update index.html
複製程式碼

相關文章