当前位置: 首页 > news >正文

git branch常用分支操作

文章目录

  • 前言
  • 远程仓库
  • 建立联系
    • 本地创建文件夹并进入
    • 初始化仓库
      • 临时插播好奇心(不在流程中)
    • 查询远程仓库
    • 与远程仓库建立对应关系
  • 第一个分支
    • 添加README文件
    • 查询当前分支
    • 将分支推送到远程仓库
  • 分支操作
    • 新建分支
    • 切换分支
    • 查看本地分支
    • 查看远程分支
    • 查看所有分支
    • 将本地分支推送到远程仓库
    • 查看本地分支与远程分支对应关系
    • 删除本地分支
    • 删除远程分支
    • 获取远程主分支到本地
    • 获取远程其他分支到本地
  • 常用集合
  • 总结

前言

最近代码的版本控制工具由SVN换成了Git,只用管理个人项目常用的灵魂三步git addgit commitgit push看来是行不通了,之前虽然也一直在用 Git,但是用法很有限,主要集中在前面提到的三步,所以为了更好的工作,我决定还是好好总结一下。

分支在Git的操作里有着很重要的地位,代表了不同的开发线路,创建一个分支,也就多了一个索引文件,相比于SVN分支拷贝全部文件来说来方便的多,所以Git使得按功能分支的开发模式变得非常简单,在开发过程中常常需要对分支进行操作。

远程仓库

本来就几个分支,操作上也没有太麻烦,但是加入了远程仓库以后,事情变得复杂起来。有了远程仓库一般意味着代码开发需要多人合作了,这时候常常会产生冲突,分支合并时也变得不那么容易了。

远程仓库其实也很好理解,就是放在远处用来保存代码资源的一个仓库,其实和本地的代码库没有什么区别,这个远程仓库主要是为了把大家修改的代码都合并到一起,给大家提供一个统一的目标点。

远程仓库究竟有多远,常见的代码托管平台:githubgitlab、码云都可以提供远程仓库,如果你在月球上放置一台可以联网的代码仓库服务器,那么距离就是38.4万千米,但是远程仓库也可以很近,你也可以把本机电脑的D盘里的代码仓库作为E盘的代码仓库的远程仓库,或许远程仓库可能只和你隔了一个文件夹。

由于网络的原因,githubgitlab 访问常常很慢,所以为了做练习测试推送,我在码云创建了一个仓库 gitstart,它的地址大概是这个样子:git@gitee.com: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 git@gitee.com:myname/gitstart.git

albert@homepc MINGW64 /d/gitstart (master)
$ git remote -v
origin  git@gitee.com:myname/gitstart.git (fetch)
origin  git@gitee.com:myname/gitstart.git (push)

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

这一步需要注意,origin看起来就是一个远程仓库的别名,代表着 git@gitee.com:myname/gitstart.git 这个代码仓库,刚刚提到过,这个远程仓库也可以是本地的,所以你添加git remote add origin d:/test 也是可以的,就表明 gitstart 的远程仓库是本地的 test 仓库。

第一个分支

刚刚说过,现在本地库的状态有些特殊,实际上刚刚在码云上创建的 git@gitee.com: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

总结

  • 以上这些命令都是在本地测试过的,可能考虑的不太全面,不过没关系,以后的分支操作还会补充到这里。
  • 这些命令在有些特殊的情况下使用可能会遇到问题,如果大家发现了问题请及时指出,我会尽快修改的。

相关文章:

  • git checkout/git reset/git revert/git restore常用回退操作
  • 没想到C++中的std::remove_if()函数历史还挺悠久
  • git stash帮你在切换分支前暂存不想提交的修改
  • Win10通过带命令行的安全模式清除顽固的广告弹窗文件
  • C++11中的时间库std::chrono(引发关于时间的思考)
  • .bat批处理(九):替换带有等号=的字符串的子串
  • 简单聊聊C/C++中的左值和右值
  • C++11在左值引用的基础上增加右值引用
  • 汇编指令入门级整理
  • 使用c++filt命令还原C++编译后的函数名
  • 配置Beyond Compare 4作为git mergetool来解决git merge命令导致的文件冲突
  • git在回退版本时HEAD~和HEAD^的作用和区别
  • 对称加密、非对称加密、公钥、私钥究竟是个啥?
  • 认证、HTTPS、证书的基本含义
  • 码龄10年工作6年的搬砖小哥,最常访问的学习网站都在这里了
  • canvas绘制圆角头像
  • CAP 一致性协议及应用解析
  • Laravel 实践之路: 数据库迁移与数据填充
  • LeetCode18.四数之和 JavaScript
  • react 代码优化(一) ——事件处理
  • React16时代,该用什么姿势写 React ?
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • select2 取值 遍历 设置默认值
  • Spring Boot快速入门(一):Hello Spring Boot
  • Vue2.0 实现互斥
  • 从零开始学习部署
  • 如何实现 font-size 的响应式
  • 如何使用 JavaScript 解析 URL
  • 如何学习JavaEE,项目又该如何做?
  • 深入浅出webpack学习(1)--核心概念
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • Spring Batch JSON 支持
  • 通过调用文摘列表API获取文摘
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​力扣解法汇总946-验证栈序列
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #Linux(帮助手册)
  • (javascript)再说document.body.scrollTop的使用问题
  • (libusb) usb口自动刷新
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (五)网络优化与超参数选择--九五小庞
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)scrum常见工具列表
  • (转)原始图像数据和PDF中的图像数据
  • *上位机的定义
  • .NET CORE 第一节 创建基本的 asp.net core
  • .net refrector
  • .NET中winform传递参数至Url并获得返回值或文件
  • @SuppressWarnings注解
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BZOJ 1040] 骑士