git branch常用分支操作

前言

最近代碼的版本控制工具由SVN換成了Git,只用管理個人項目常用的靈魂三步git addgit commitgit push看來是行不通了,之前雖然也一直在用 Git,但是用法很有限,主要集中在前面提到的三步,所以爲了更好的工作,我決定還是好好總結一下。

分支在Git的操作裏有着很重要的地位,代表了不同的開發線路,創建一個分支,也就多了一個索引文件,相比於SVN分支拷貝全部文件來說來方便的多,所以Git使得按功能分支的開發模式變得非常簡單,在開發過程中常常需要對分支進行操作。

遠程倉庫

本來就幾個分支,操作上也沒有太麻煩,但是加入了遠程倉庫以後,事情變得複雜起來。有了遠程倉庫一般意味着代碼開發需要多人合作了,這時候常常會產生衝突,分支合併時也變得不那麼容易了。

遠程倉庫其實也很好理解,就是放在遠處用來保存代碼資源的一個倉庫,其實和本地的代碼庫沒有什麼區別,這個遠程倉庫主要是爲了把大家修改的代碼都合併到一起,給大家提供一個統一的目標點。

遠程倉庫究竟有多遠,常見的代碼託管平臺:githubgitlab、碼雲都可以提供遠程倉庫,如果你在月球上放置一臺可以聯網的代碼倉庫服務器,那麼距離就是38.4萬千米,但是遠程倉庫也可以很近,你也可以把本機電腦的D盤裏的代碼倉庫作爲E盤的代碼倉庫的遠程倉庫,或許遠程倉庫可能只和你隔了一個文件夾。

由於網絡的原因,githubgitlab 訪問常常很慢,所以爲了做練習測試推送,我在碼雲創建了一個倉庫 gitstart,它的地址大概是這個樣子:[email protected]:myname/gitstart.git,創建的方法一搜一大把,上面提到的幾個託管平臺,在哪創建都可以,一定要記住地址,因爲後面還要用到。

建立聯繫

本地創建文件夾並進入

albert@homepc MINGW64 /d
$ mkdir gitstart

albert@homepc MINGW64 /d
$ cd gitstart/

albert@homepc MINGW64 /d/gitstart
$

這裏的文件夾名字可以和遠程倉庫不同,但是爲了看起來方便對應,還是取相同的名字好一點。

初始化倉庫

albert@homepc MINGW64 /d/gitstart
$ git init
Initialized empty Git repository in D:/gitstart/.git/

albert@homepc MINGW64 /d/gitstart (master)
$

臨時插播好奇心(不在流程中)

目前這個狀態有點意思,初始化完之後,(master) 這個字符串表示當前是在 master分支,查一下日誌看看:

albert@homepc MINGW64 /d/gitstart (master)
$ git log
fatal: your current branch 'master' does not have any commits yet

albert@homepc MINGW64 /d/gitstart (master)
$

提示也是正確的,說 master分支沒有任何提交,但是我們查詢一下分支看看:

albert@homepc MINGW64 /d/gitstart (master)
$ git branch -a

albert@homepc MINGW64 /d/gitstart (master)
$

居然是空的,沒有分支,查詢 .git\HEAD 文件發現裏面有一行 ref: refs/heads/master,說明當前分支時 master,但是爲什麼查詢分支沒有結果呢?

打開 .git\refs\heads 目錄,發現這個文件夾下根本沒有 master文件,其實想想也對,Git 中的分支其實對應着 commit id,現在什麼都沒有提交,master 也就找不到 commit id,所以就是有 master 文件,裏面也不知道寫什麼。

查詢遠程倉庫

albert@homepc MINGW64 /d/gitstart (master)
$ git remote -v

albert@homepc MINGW64 /d/gitstart (master)
$

依舊什麼內容都沒有,說明還沒有和遠程倉庫建立聯繫。

與遠程倉庫建立對應關係

albert@homepc MINGW64 /d/gitstart (master)
$ git remote add origin [email protected]:myname/gitstart.git

albert@homepc MINGW64 /d/gitstart (master)
$ git remote -v
origin  [email protected]:myname/gitstart.git (fetch)
origin  [email protected]:myname/gitstart.git (push)

albert@homepc MINGW64 /d/gitstart (master)
$

這一步需要注意,origin看起來就是一個遠程倉庫的別名,代表着 [email protected]:myname/gitstart.git 這個代碼倉庫,剛剛提到過,這個遠程倉庫也可以是本地的,所以你添加git remote add origin d:/test 也是可以的,就表明 gitstart 的遠程倉庫是本地的 test 倉庫。

第一個分支

剛剛說過,現在本地庫的狀態有些特殊,實際上剛剛在碼雲上創建的 [email protected]:myname/gitstart.git 庫也很特殊,他們都沒有真正的分支,這時只要我們成功提交一次,創建一個commit id,就相當於初始化了master分支。

添加README文件

albert@homepc MINGW64 /d/gitstart (master)
$ echo "learn git branch command">README.md

albert@homepc MINGW64 /d/gitstart (master)
$ git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory

albert@homepc MINGW64 /d/gitstart (master)
$ git commit -m"add readme file"
[master (root-commit) 3226b63] add readme file
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

查詢當前分支

albert@homepc MINGW64 /d/gitstart (master)
$ git branch -a
* master

這次可以是出現了,分支爲 master,前面的 * 表示爲當前分支。

將分支推送到遠程倉庫

albert@homepc MINGW64 /d/gitstart (master)
$ git push -u origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 248 bytes | 248.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-3.8]
To gitee.com:myname/gitstart.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

至此,本地倉庫和遠程倉庫就建立了聯繫,下面可以開始學習 Git 分支命令了。

分支操作

新建分支

新建分支可以使用 git branch branch_name 命令,以下就是一個創建名爲 release 分支的命令:

albert@homepc MINGW64 /d/gitstart (master)
$ git branch release

也可以使用 git checkout -b branch_name 來創建一個新分支,創建完會自動切換到新分支:

albert@homepc MINGW64 /d/gitstart (master)
$ git checkout -b dev
Switched to a new branch 'dev'

albert@homepc MINGW64 /d/gitstart (dev)
$

切換分支

這是一個很奇怪的命令,命令格式爲 git checkout branch_name,總感覺 checkout 子命令包攬了不屬於自己的工作,如果在git branch的基礎上加一個參數會更合理的一點,但這和切換分支的實際含義可能還有關係,切換分支其實就是修改HEAD文件中的 commit id,而沒有真正的發生切換。

albert@homepc MINGW64 /d/gitstart (dev)
$ git checkout release
Switched to branch 'release'

albert@homepc MINGW64 /d/gitstart (release)
$ git checkout dev
Switched to branch 'dev'

albert@homepc MINGW64 /d/gitstart (dev)
$

查看本地分支

像剛纔我們創建的 release 分支和 dev 分支都是在本地創建的,這樣的分支通過 git branch 命令就可以查看

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch
* dev
  master
  release

這樣就列舉了本地的所有分支,在當前分支名字 dev 前面哈還有一個 * 作爲標記

查看遠程分支

只要在上面的命令基礎上加上 -r 參數就行了

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -r
  origin/master

查詢到的分支只有 origin/master 一個,這個分支是一開始我們進行第一次提交產生 master 分支之後,通過 git push -u origin master 推送到遠程倉庫的,所以現在只有一個。

查看所有分支

所有分支包括本地分支和遠程分支,將 -r 參數換成 -a 參數就可以了

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
  master
  release
  remotes/origin/master

將本地分支推送到遠程倉庫

其實之前已經操作過了,可以試着複習一下,git push -u origin branch_name,其實這是一個簡寫,-u 可以寫成 --set-upstream 表示設置上游分支,其實就是和遠程倉庫的分支建立聯繫。

branch_name 也是 local_branch_name:remote_branch_name的一種簡寫,冒號前表示本地分支,冒號後面表示遠程分支,如果只寫一個就表示兩個分支名相同,遠程倉庫中如果沒有這個分支就會新建一個。

也就是說 git push -u origin devgit push--set-upstream origin dev:dev 是一樣的,下面來試一下,然後查看一下分支:

albert@homepc MINGW64 /d/gitstart (dev)
$ git push -u origin dev
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-3.8]
remote: Create a pull request for 'dev' on Gitee by visiting:
remote:     https://gitee.com/myname/gitstart/pull/new/myname:dev...myname:master
To gitee.com:myname/gitstart.git
 * [new branch]      dev -> dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
  master
  release
  remotes/origin/dev
  remotes/origin/master

冒號前後的米名字是不是一定相同呢?完全沒有必要,我們可以讓本地的 release 分支對應遠程的 master 分支,只不過這樣怪怪的,但是操作上完全可以的。

albert@homepc MINGW64 /d/gitstart (dev)
$ git checkout release
Switched to branch 'release'

albert@homepc MINGW64 /d/gitstart (release)
$ git push -u origin release:master
Everything up-to-date
Branch 'release' set up to track remote branch 'master' from 'origin'.

查看本地分支與遠程分支對應關係

這個也是剛剛知道的,可以使用 git branch -vv 命令,注意是兩個 v:

albert@homepc MINGW64 /d/gitstart (release)
$ git branch -vv
  dev     3226b63 [origin/dev] add readme file
  master  3226b63 [origin/master] add readme file
* release 3226b63 [origin/master] add readme file

執行這個命令之後可以看出,本地的 masterrelease 分支都對應着遠程的 master 分支

刪除本地分支

我們先複習一下新建分支,然後把它推送到遠程倉庫,再使用 git branch -d branch_name 命令進行刪除

albert@homepc MINGW64 /d/gitstart (release)
$ git checkout -b feature_test
Switched to a new branch 'feature_test'

albert@homepc MINGW64 /d/gitstart (feature_test)
$ git push origin feature_test
Total 0 (delta 0), reused 0 (delta 0)
 remote: Powered by GITEE.COM [GNK-3.8]
remote: Create a pull request for 'feature_test' on Gitee by visiting:
remote:     https://gitee.com/myname/gitstart/pull/new/myname:feature_test...myname:master
To gitee.com:myname/gitstart.git
 * [new branch]      feature_test -> feature_test

albert@homepc MINGW64 /d/gitstart (feature_test)
$ git branch -a
  dev
* feature_test
  master
  release
  remotes/origin/dev
  remotes/origin/feature_test
  remotes/origin/master

開始刪除分支,刪除之前記得切換到別的分支,否則刪除不成功

albert@homepc MINGW64 /d/gitstart (feature_test)
$ git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -d feature_test
Deleted branch feature_test (was 3226b63).

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
  master
  release
  remotes/origin/dev
  remotes/origin/feature_test
  remotes/origin/master

刪除遠程分支

通過上面的操作我們發現只刪除了本地的分支,遠程的分支還在,要想刪除遠程分支,需要使用 git push origin --delete branch_name 命令

albert@homepc MINGW64 /d/gitstart (dev)
$ git push origin --delete feature_test
remote: Powered by GITEE.COM [GNK-3.8]
To gitee.com:myname/gitstart.git
 - [deleted]         feature_test

albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
  master
  release
  remotes/origin/dev
  remotes/origin/master

這次再查看時發現遠程分支也被刪掉了。

獲取遠程主分支到本地

其實 Git 的克隆命令默認就是把遠程倉庫的主分支下載到本地,我們可以使用 git clone 遠程地址 本地文件夾 命令來克隆一個倉庫,如果本地文件夾省略,則默認新建一個與倉庫名相同的文件夾:

albert@homepc MINGW64 /d
$ git clone https://gitee.com/myname/gitstart.git gitstartcopy
Cloning into 'gitstartcopy'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.

albert@homepc MINGW64 /d
$ cd gitstartcopy/

albert@homepc MINGW64 /d/gitstartcopy (master)
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master

獲取遠程其他分支到本地

從上面命令執行後的結果來看,當前本地倉庫中只有 master 分支,其他的分支都是在遠程倉庫上,這時可以用 git checkout branch_name 命令來下載遠程分支:

albert@homepc MINGW64 /d/gitstartcopy (master)
$ git checkout dev
Switched to a new branch 'dev'
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

albert@homepc MINGW64 /d/gitstartcopy (dev)
$ git branch -a
* dev
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/dev
  remotes/origin/master

albert@homepc MINGW64 /d/gitstartcopy (dev)
$ git branch -vv
* dev    3226b63 [origin/dev] add readme file
  master 3226b63 [origin/master] add readme file

看到這裏可能會疑惑了,git checkout branch_name 不是切換分支的命令嗎?實際上當 branch_name 分支在本地不存在而遠程倉庫存在時,這個命令與 git checkout -b <branch> --track <remote>/<branch> 含義相同,會在本地新建一個分支,並與遠程分支建立聯繫。

常用集合

  • 新建分支:git checkout -b branch_name
  • 切換分支:git checkout branch_name
  • 查看分支:git branch -a
  • 刪除分支:git branch -d branch_name
  • 推送分支到遠程:git push origin branch_name
  • 刪除遠程的分支:git push origin --delete branch_name
  • 拉取遠程分支到本地:git checkout branch_name
  • 查詢分支的對應關係:git branch -vv

總結

  • 以上這些命令都是在本地測試過的,可能考慮的不太全面,不過沒關係,以後的分支操作還會補充到這裏。
  • 這些命令在有些特殊的情況下使用可能會遇到問題,如果大家發現了問題請及時指出,我會盡快修改的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章