git-03-分支

说明

本篇文章是本人回顾git知识点时从《progit》一书中摘抄出来的笔记,毕竟好记性不如烂笔头嘛,不然我也不会回顾了……
另请大神绕路,不喜勿喷……

1 基础知识

初始提交

$ git init repo-1
Initialized empty Git repository in H:/tmp/git-test/repo-1/.git/

$ cd repo-1/

# 建立三个测试文件
$ touch readme.md config.xml db.properties

# 加入暂存区 待下次提交
$ git add readme.md config.xml db.properties

# 提交
$ git commit -m 'init project'

此时的git仓库中的对象可能大致如下图所示:

blob

说明:

  • blob对象:保存着文件快照
  • tree对象:记录着目录结构和blob对象索引
  • commit对象:包含着指向前述树对象的指针和所有提交信息

做些修改再提交

# 修改readme.md
$ echo "haha" >> readme.md
$ git add .
$ git commit -m "second commit"

# 修改db.properties
$ echo "db.user=root" >> db.properties
$ git add .
$ git commit -m "db.properties modified"


# 看看此时的提交历史
$ git log --oneline --decorate --all
7240135 (HEAD -> master) db.properties modified
828bc57 second commit
e314b67 init project

此时的仓库中快照可能是下面这个样子:

snapshort

就像前面说的,git不存储文件差异,每次提交都是记录一次文件的快照,担任文件内容不变的时候不会重复存储快照了。

每个commit一般都有其父commit对象(除了第一个commit对象)。

git的分支本质也就是指向某个特定commit对象的指针。

这样的话,在分支切换、分支建立的时候,都是非常迅速的。

当你首次提交之后,git会建立一个名为master的默认分支。即使你不显示地主动创建分支,你也是在master分支上工作的。每次提交后,都是指向最后一个commit对象。也就是说,在commit的时候这个指针是自动移动的。

在你创建新分支的时候,其实是创建了一个新的指针。

2 分支基本操作

2.1 新建分支

# 建立名为b1的分支
$ git branch b1

此时的分支信息如下所示:

新建分支

  • 此时的master和b1分支都指向最新的一个commit对象
  • 上图中的HEAD指的是一个记录当前所处本地分支的指针。也就是说HEAD是当前分支的别名
  • 在你使用git branch b1建立分支后,并没有自动切换到新分支b1上去
# 此时的b1和master都是指向特征码为7240135的commit对象
# HEAD -> master表明,当前所处分支任然是master分支
$ git log --oneline --decorate
7240135 (HEAD -> master, b1) db.properties modified
828bc57 second commit
e314b67 init project

2.2 切换分支

$ git checkout b1
Switched to branch 'b1'


# HEAD -> b1 表明,当前所处分支是b1
$ git log --oneline --decorate
7240135 (HEAD -> b1, master) db.properties modified
828bc57 second commit
e314b67 init project

HEAD -> b1 表明,当前所处分支是b1。那么此时的分支图示应该像下面这样:

branch-b1

2.3 新分支上做修改

# 在分支b1上修改文件readme.md
$ echo "new line @ brach b1" >> readme.md

$ git add readme.md
$ git commit -m "modified on b1 - 1"

查看此时的提交历史

$ git log --oneline --decorate
cf385f4 (HEAD -> b1) modified on b1 - 1
7240135 (master) db.properties modified
828bc57 second commit
e314b67 init project

可以得出:

  • 最新的一次commit对象是在分支b1上做的
  • 当下处于b1分支

那么此时的分支示例图大概如下:

新分支上修改文件

2.4 分支合并

回到master分支

$ git checkout master
Switched to branch 'master'

$ git log --decorate --oneline
7240135 (HEAD -> master) db.properties modified
828bc57 second commit
e314b67 init project

在master分支上修改db.properties

$ cat db.properties
db.user=root

# 在master分支上修改db.properties
$ echo "db.password=123" >> db.properties

$ git add db.properties
$ git commit -m "db.properties modified on master"

此时的分支示例图

$ git log --decorate --oneline --graph
* 957a3d0 (HEAD -> master) db.properties modified on master
* 7240135 db.properties modified
* 828bc57 second commit
* e314b67 init project

分支分叉

  • 此时分支已经有了分叉
  • 可以在需要的时候合并

合并b1分支到master

$ git merge b1
Merge made by the 'recursive' strategy.
 readme.md | 1 +
 1 file changed, 1 insertion(+)

查看分支历史

$ git log --decorate --oneline --graph
*   3115451 (HEAD -> master) Merge branch 'b1'
|\
| * cf385f4 (b1) modified on b1 - 1
* | 957a3d0 db.properties modified on master
|/
* 7240135 db.properties modified
* 828bc57 second commit
* e314b67 init project

分支合并

3 分支管理

列出所有分支

$ git branch
  b1
* master

删除分支

git branch -d <branch-name>

master分支前面的星号表示当前HEAD指向master,也就是说当前处于master分支。

查看每一个分支的最后一次提交

$ git branch -v
  b1     cf385f4 modified on b1 - 1
* master 3115451 Merge branch 'b1'

查看已经合并到/尚未合并到当前分支的分支

# b1分支已经合并到当前分支
$ git branch --merged
  b1
* master

# 尚未合并到当前分支的分支
$ git branch --no-merged

此处使用 git branch --merged 列出的这个列表中分支名字前没有星号的分支通常可以使用 git branch -d 删除掉。因为在这些分支上所作的修改已经被合并到其他分支了。

4 远程仓库与远程分支

4.1 远程仓库

远程仓库是指托管在因特网或其他网络中的项目的版本库。可以有若干个远程仓库。

$ git clone https://github.com/java-template/jt-808-protocol.git

$ cd jt-808-protocol/

# 列出指定的每一个远程服务器的简写
(master) $ git remote
origin

(master) $ git ls-remote
From https://github.com/java-template/jt-808-protocol.git
7c86e1cde856183e794b31ac72f2b02377b6f4b8    HEAD
7c86e1cde856183e794b31ac72f2b02377b6f4b8    refs/heads/master


# 选项 -v,显示简写与其对应的 URL
(master) $ git remote -v
origin  https://github.com/java-template/jt-808-protocol.git (fetch)
origin  https://github.com/java-template/jt-808-protocol.git (push)

4.2 远程仓库管理

新增远程仓库

git remote add <name> <url>
# 添加简写名为another的远程仓库
(master) $ git remote add another https://github.com/java-template/jt-808-protocol.git

# 列出所有的远程仓库
(master) $ git remote -v
another https://github.com/java-template/jt-808-protocol.git (fetch)
another https://github.com/java-template/jt-808-protocol.git (push)
origin  https://github.com/java-template/jt-808-protocol.git (fetch)
origin  https://github.com/java-template/jt-808-protocol.git (push)

# 此时可以使用another来代替整个URL来使用
(master) $ git pull another 
From https://github.com/java-template/jt-808-protocol
 * [new branch]      master     -> another/master
You asked to pull from the remote 'another', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.

注意

  • 如果你使用 clone 命令克隆了一个仓库,命令会自动将其添加为远程仓库并默认以 origin 为简写

重命名远程仓库

# 将远程服务器another重命名为other
(master) $ git remote rename another other
(master) $ git remote -v
origin  https://github.com/java-template/jt-808-protocol.git (fetch)
origin  https://github.com/java-template/jt-808-protocol.git (push)
other   https://github.com/java-template/jt-808-protocol.git (fetch)
other   https://github.com/java-template/jt-808-protocol.git (push)

删除远程仓库

# 删除远程服务器other
(master) $ git remote rm other 
(master) $ git remote -v
origin  https://github.com/java-template/jt-808-protocol.git (fetch)
origin  https://github.com/java-template/jt-808-protocol.git (push)

4.3 从远程仓库获取数据

git fetch [remote-name]
  • 此命令会访问远程仓库,从中拉取所有你还没有的数据
  • 执行完成后,你将会拥有那个远程仓库中所有分支的引用
  • 但是此命令并不会自动merge,也就是说需要你手动合并
git pull
  • 该命令可以认为是git fetchgit merge的组合
  • 当然,自动合并出错还得你自己解决冲突了

4.4 推送数据到远程分支

远程分支以 (remote)/(branch) 形式命名,或称之为唯一标识它。
比如origin/master表示远程服务器orgin上的master分支,origin/iss256表示origin服务器上的一个名为iss256的分支。

git push [remote-name] [branchname]

将 master 分支推送到 origin 服务器

$ git push origin master

4.5 一点说明

当clone一个远程仓库时,会自动建立一个master分支来跟踪origin/master分支

  • origin是默认的远程服务器的名称
  • master是默认的分支名
  • 当然,origin和master除了是默认的名称外,没有其他任何特别之处

至于跟踪分支的细节,请看下文

5 跟踪分支

跟踪分支是与远程分支有直接关系的本地分支。

也就是说:在一个跟踪分支上执行 git pull,Git 能自动地识别去哪个服务器上抓取、也知道将fetch到的数据合并到哪个分支。

5.1 创建跟踪分支

  • 当clone一个远程仓库时,会自动建立一个master分支来跟踪origin/master分支
  • 使用git checkout -b [branch] [remotename]/[branch]创建跟踪分支
  • 或者可以在checkout的时候使用--track选项
# 创建一个名为another-track-branch的分支作为origin/master的跟踪分支
(master) $ git checkout -b another-track-branch origin/master Branch another-track-branch set up to track remote branch master from origin.
Switched to a new branch 'another-track-branch'
(another-track-branch) $ 

5.2 修改跟踪分支

可以使用 -u--set-upstream-to 选项运行 git branch 来显式地设置跟踪的远程分支

# 设置当前分支跟踪origin服务器的master分支
(another-track-branch) $ git branch --set-upstream-to origin/master 

5.3 查看跟踪分支

(another-track-branch) $ git branch -vv
* another-track-branch 7c86e1c [origin/master] 调试工具
  master               7c86e1c [origin/master] 调试工具
  test1                7c86e1c 调试工具
(another-track-branch) $ git branch -vv

可以看出,此处:

  • another-track-branch分支和master分支都在跟踪origin/master分支
  • another-track-branch前面的星号表示目前处于another-track-branch分支
  • test1分支没有跟踪任何分支

参考资料

  • 《progit》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值