Git的基本工作原理
在版本库中(repository),Git维护两个主要的数据结构:对象库(object store)和索引(index)。所有这些版本库数据存放在工作目录根目录下一个名为.git 的隐藏子目录中
Git 对象 object
- 文件的每一个版本表示为一个块(blob), 一个blob保存一个文件的数据,但不包含任何关于这个文件的元数据,甚至连文件名也没有
- 一个目录树(tree)对象代表一层目录信息。它记录blob标识符、路径名和在一个目录里所有文件的一些元数据。它也可以递归引用其他目录树或子树对象,从而建立一个包含文件和子目录的完整层次结构。
- 一个提交(commit)对象保存版本库中每一次
变化
的元数据,包括作者、提交者、提交日期和日志消息。每一个提交对象指向一个目录树对象,这个目录树对象在一张完整的快照中捕获提交时版本库的状态。最初的提交或者根提交(root commit)是没有父提交的。大多数提交都有一个父提交 - 一个标签对象分配一个任意的且人类可读的名字给一个特定对象,通常是一个提交对象。虽然9da581d910c9c4ac93557ca4859e767f5caf5169指的是一个确切且定义好的提交,但是一个更熟悉的标签名(如Ver-1.0-Alpha)可能会更有意义.
Git 索引 index
-
索引是一个临时的、动态的二进制文件,它描述整个版本库的目录结构。更具体地说,索引捕获项目在某个时刻的整体结构的一个版本。项目的状态可以用一个提交和一棵目录树表示,它可以来自项目历史中的任意时刻,或者它可以是你正在开发的未来状态。
-
你通过执行Git命令在索引中暂存(stage)变更。变更通常是添加、删除或者编辑某个文件或某些文件。索引会记录和保存那些变更,保障它们的安全直到你准备好提交了。还可以删除或替换索引中的变更。因此,索引支持一个由你主导的从复杂的版本库状态到一个可推测的更好状态的逐步过渡。
-
有了暂存区,我们可以把当前的工作区修改分为几组放入暂存区然后提交。这就是Git常常被提到的分批提交的概念
-
Git的索引不包含任何文件内容,它仅仅追踪你想要提交的那些内容。当执行git commit命令的时候,Git会通过检查索引而不是工作目录来找到提交的内容
Git的文件分类/状态
git 的文件分类: 已追踪(git add后的)
,被忽略(.gitignore中的)
, 未追踪(剩下的其他)
在任何编辑之后,提交变更之前,请执行git add命令,用最新版本的文件去更新索引。
如果不这么做,你将会得到两个不同版本的文件:一个是在对象库里被捕获并被索引引用的,另一个则在你的工作目录下。
Git 的基本概念
origin 指的是什么
origin 是工程代码的 远程地址在本地的一个默认别名
那么如何来理解呢:
- 假如自己的一个代码库(repository)可以存放在你的电脑里
- 同时也可以把代码库托管到Github的服务器上,例如在 https://github.com/user1/repository
- git clone https://github.com/user1/repository
- 当在本地clone一个托管在Github上代码库时,git为你默认创建的指向这个远程代码库的标签 叫origin
添加和关联远程代码仓库的操作
git remote add origin https://github.com/your_name/****.git
## 当你再执行 git remote -v 时,就会发现 origin所对应远程端的 fatch和push的地址
origin https://github.com/user/repository.git (fetch)
origin https://github.com/user/repository.git (push)
# 当然,如果本地代码不是通过clone过来的,例如是先在本地git init的,然后想托管到GitHub等服务器上
## 那么可以手动指定远程代码库的标签(别名) 和地址
git remote add origin https://github.com/your_name/****.git
# 注意:同一个本地代码库可以同时对应多个远程仓库,例如我们我们想把代码同时保存在gitee 和 github上
## 比如我们的github 对应origin, 那么我们添加一个gitee的别名并指向一个具体的远程地址
git remote add gitee https://gitee.com/user_name/****.git
## 这是再 git remote -v, 就会发现本地仓库指向了两个远程代码托管仓库
$ git remote -v
origin https://github.com/user/test.git (fetch)
origin https://github.com/user/test.git (push)
gitee https://gitee.com/user/test.git (fetch)
gitee https://gitee.com/user/test.git (push)
git push origin master # 把本地代码的当前分支 push到 github的 master分支
git push gitee master # 把本地代码的当前分支 push到 gitee的 master分支
branch 本地分支与远程分支
首先明确 Git中 branch指的是什么?
- Git中的分支(branch), 其本质仅仅是
一个指向commit对象的可变指针
, 一个分支就对应着某个对象的提交历史。
比如我们有master 和 test两个分支,
当我们在test分支进行一次commit提交后,此时master分支指针没有变化,test分支向后移动了一个结点
-
branch的巧妙设计,使得当我们基于某一个版本新建一个分支时,不需要将所有数据进行复制
-
只要重新创建一个分支的指针指向你需要从哪里开始创建分支的提交对象(commit),然后进行修改再提交时,那么新分支的指针就会向后移动一个节点,指向你最新提交的这个commit对象
-
HEAD分支时一个特殊的branch, 代表着最后一次commit, 即最新的指针
远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某个项目时,需要管理这些远程仓库,以便推送或拉取数据,分享各自的工作进展.管理远程仓库的工作,包括添加远程库,移除废弃的远程库,管理各式远程库分 支,定义是否跟踪这些分支。
本地分支与远程分支应该有一个追踪关系,因为当前分支没有追踪远程指定的分支的话,当前分支指定的版本快照不知道要作为服务器哪一个分支的版本快照的子节点。简单来说就是:不知道要推送给哪一个分支。这样在push 和 pull时就会报错。
如何建立本地分支与远程分支的连接关系
# 1. git clone
git clone
克隆时自动将创建好的本地master分支追踪origin/master分支
# 2. git checkout -b
git checkout -b develop origin/develop
在远程分支的基础上建立本地develop分支,并且让develop分支追踪origin/develop远程分支。
# 3. git branch --set-upstream
git push --set-upstream origin ORB-SLAM
命令 | 功能 | 示例 |
---|---|---|
git branch | 不带参数:列出本地已经存在的分支,并且在当前分支的前面用* 标记 | |
git branch -r | 查看远程版本库分支列表 | |
git branch -a | 查看所有分支列表,包括本地和远程 | |
git branch -vv | 可以查看本地分支对应的远程分支 | |
git branch branch_name | 创建名为branch_name的分支,创建分支时需要是最新的环境,创建分支但依然停留在当前分支, (新的分支就是当前分支的快照,未保存的文件也会存在在新分支中存在) | |
git branch -m oldName newName | 给分支重命名 | |
git branch -d // --dalete branch_name | 删除本地分支该分支必须完全和它的上游分支merge完成(了解上游分支,可以点击查看链接),如果没有上游分支,必须要和HEAD完全merge,不然无法删除 | |
git branch -D branch_name | 不检查merge状态,直接删除本地分支 | |
git push origin -d // --delete branch_name | 同时删除本地分支和远程分支 | |
git branch --delete --remotes / | 断除了该分支本地和远程的连接 | git branch -rd origin/X |
git branch --set-upstream branch-name_a origin/branch-name_b | 把本地的branch-name_a 与远程分支 origin/branch-name_b建立追踪 | |
git checkout branch_name | 1. 如果本地有这个分支则直接切过去,2.如果远程服务器有多个分支,通过这个指令,会在本地创建一个与远端同名的分支,并建立本地与远端的对应关系, 3. 如果本地远程都没有这个分支,则无法切换 | |
git checkout -b branch_name | 如果分支存在则只切换分支,若不存在则基于当前commit创建新分支并切换到该分支 | |
git checkout filename | 放弃单个文件的修改 | |
git checkout . | 放弃当前目录下的修改 |
Git 的基本操作
git 初始化与基本信息配置
命令 | 功能 | 示例 |
---|---|---|
git init | 初始化一个空白的Git repository | |
git config --global color.ui auto | 将color.ui设置为auto,让命令输出更加可读 | |
git config --global -l | 查看global配置信息 | |
git config --local -l | 查看local 配置信息 | |
git config --global user.name/email | 设置global 提交作者name | git config --global user.name “Jon Loeliger” |
git config --local user.email | 设置local 提交作者email | git config user.email “jdl@example.com” |
git remote -v | 查看远程代码库的标签和地址 | |
git remote add | 添加远程代码库的标签和地址 | git remote add origin https://github.com/user_name/****.git |
git push
- 远程的主机名一般是 origin
- 当本地分支和远程分支相同时可以省略
- 省略远程分支,表示将本地分支推送到相同名称的远程分支
- 省略本地分支,表示
删除
相同名称的远程分支, [!小心使用
因为这等同于推送一个空的本地分支到远程分支]
git push <远程主机名> <本地分支名>:<远程分支名>
git push origin master:master #将本地的master分支推送到origin主机的master分支
# git push <来源地是本地>:<推送目的地是远程>
# 与git pull 相反<来源 远程分支>:<拉到本地>
### 省略
git push origin master #省略远程 master,将本地的master分支推送到origin主机的master分支
git push origin :master #省略本地 master, 将远程段的master删除
git push origin --delete master #删除origin主机的master分支,等价于上面命令
# 如果当前分支与远程分支之间存在追踪关系,则本地分支和远程分支都可以省略。
git push origin #将当前分支推送到origin主机的对应分支。
git push #如果当前分支只有一个追踪分支,那么主机名都可以省略
# 如果当前分支与多个主机存在追踪关系,则可以使用-u选项指定一个默认主机,
# 这样后面就可以不加任何参数使用git push
git push -u origin master
## 如果 git的本地仓库和远程仓库没有建立追踪关系,可以通过 --set-upstream指定
git push --set-upstream origin ORB-SLAM
#把本地的ORB-SLAM 推送到origin远程端的ORB-SLAM
git pull
git stash 保存/恢复工作进度
- stash命令可用于临时保存和回复修改,可跨分支
- 注意stash只能stash 被追踪的切没有被add进缓存区的文件,(比如你修改 删除的文件,新加的就不行)
命令 | 说明 |
---|---|
git stash list | 查看本地所有stash list |
git stash [save message] | 保存当前当前修改工作至stash, 最好写一下message, 不然容易忘记缓存了什么 |
git stash show stash@{num} | 查看指定的stash和当前目录差异 |
git stash pop stash@{num} | 恢复某次stash工作到当前分支,只恢复一次后,从list移除了 |
git stash apply stash@{num} | 恢复某次stash工作到当前分支,可恢复一次后,在list中还有 |
git stash drop stash@{num} | 删除某次 stash |
git stash clear | 删除所有stash, 清空了stash list |
git merge
开发工作中,需要在某个分支上修改bug或者增加功能,一种做法是直接在这个分支上修改提交,另一种做法是基于这个分支新建一个分支,然后修改,最后把修改后的分支合并到当前分支上。
git checkout -b new origin/master
## 修改 new分支内容……
git checkout master
git merge new 合并new成果到master
git branch -d new 合并之后,子分子没用可以给删除了
git push origin master ## 同步到远程端
git rebase
- git pull --rebase 合并的方法更简单
- 使用git rebase改变分支依赖(变基操作)
- 修改最近的commit, 或者合并最近多个commit
- 将一个提交分成几个
- 对提交的commit 排序
其中-i的意思是–interactive,即弹出交互式的界面让用户编辑完成合并操作
git rebase -i HEAD~10 重新组织最近十次的提交信息
git rebase -i origin/devel 变基到最新devel, 并重新组织所有提交信息
editor
pick 5c6eb73 Added repo.or.cz link pick a311a64 Reordered analogies in “Work How You Want”
pick 100834f Added push target to Makefile
…
在编辑git rebase editor的时候,注意与git log info的区别
- git log 列表中最新提交的在最上面,
- rebase editor中, 最老提交的在最上面, 最新提交的在最下面
在git rebase editor列表中, 我们能够根据需求做不同的操作
- 通过删除行来移去提交。
- 通过对几行记录重新排序,来重组提交顺序。
- pick 命令固定提交
- edit 标记一个提交需要修订。
- reword 改变日志信息。
- squash 将一个提交与其前一个合并。squash的作用就是 把一个提交“挤压”进前一个提交, 并且允许编辑合并后的提交日志
- fixup 将一个提交与其前一个合并,并丢弃日志信息.
如果你把一个提交标记为edit,Git会带你回到这个提交点,你可以修改当时的提交信息 ,甚至可以增加新的提交。修改完毕后执行 git rebase --continue
# 进入要修改的commit
git commit --amend
# 进行相应的修改
git add 对应的文件
Ctrl+X 进行更新
git rebase --continue 继续rebase
git rebase --abort 放弃修改
git merge & rebase
-
git pull = git fetch + git merge
-
git pull --rebase = git fetch + git rebase
-
假设现在有 A、B、C三次commit
-
在远程分支origin的基础上,我们在本地创建一个名为"mywork"的分支并提交了E,同时有其他人在"origin"上做了一些修改并先提交了D,这时如果我们push E其实会发生冲突的,解决冲突有merge 和 rebase两种方法,着两种方法有什么区别呢?
git merge的方式
用git pull命令把"origin"分支上的修改pull下来与本地提交合并(merge)成版本M,但这样会形成图中的菱形
git pull origin/master # 因为git pull = git fetch + git merge
# 解决merge 冲突
git push origin master
git rebase的方式
rebase相当于创建一个新的提交R,R的文件内容和上面M的一样,但我们将E提交废除,当它不存在(图中用虚线表示)。由于这种删除,rebase的好处是避免了菱形的产生,保持提交曲线为直线,让大家易于理解。
git rebase origin/master
# 解决冲突
git push origin master
# 在rebase的过程中,有时也会有conflict,这时Git会停止rebase并让用户去解决冲突
# 解决完冲突后,用git add命令去更新这些内容,然后不用执行git-commit,
# 直接执行git rebase --continue,这样git会继续apply余下的补丁。
# 在任何时候,都可以用git rebase --abort参数来终止rebase的行动,并且mywork分支会回到rebase开始前的状态。
git reset
- git add 把修改添加到缓存区
- git reset 把修改从暂存区移除
首先 使用 git reflog 查看提交版本的commit_ID
## git commit 之后如何撤销呢
git reset --soft HEAD~1 撤销当前的commit 回到上一次提交,修改的代码在本地仍会保留
默认的选项 --mixed 撤销commit 撤销git add, 保留代码改动
--soft 撤销commit 不撤销git add,保留代码改动
--hard 撤销commit 撤销add,删除代码改动
# 前者表示只是改变了HEAD的指向,本地代码不会变化,
# 我们使用git status依然可以看到,同时也可以git commit提交。
# 后者直接回改变本地源码,不仅仅指向变化了,代码也回到了那个版本时的代码,
# 所以使用是一定要小心,想清楚。
如果只是想修改git commit注释,使用 git commit --amend 会打开git编辑器,修改保存即可
git revert
取消指定的某次提交内容
#常规commit revert, git 会生成一个新的 commit,将指定的 commit 内容从当前分支上撤除
git revert <commit id>
# merge commit revert, revert的的commit的上面有两个commit节点的时候
git revert -m 1 <commit id>
git revert -m 2 <commit id>
git rm
注意:git rm --cached会删除索引中的文件并把它保留工作目录中,而git rm则会将文件从索引和工作目录中都删
# 当我们需要删除暂存区或分支上的文件, 同时工作区也不需要这个文件了, 可以使用
git rm file_path ## 本地工作区、暂存区都删除了
git commit -m 'delete somefile'
git push
# 当我们需要删除暂存区或分支上的文件, 但本地又需要使用, 只是不希望这个文件被版本控制, 可以使用
git rm --cached file_path ## 只删除暂存区(不被追踪了), 本地工作区还在
git commit -m 'delete remote somefile'
git push
git submodule
submodule 功能就是建立了当前项目与子模块之间的依赖关系:
- 子模块路径、
- 子模块的远程仓库、
- 子模块的版本号
在面对比较复杂的项目,我们有可能会将代码根据功能拆解成不同的子模块。主项目对子模块有依赖关系,却又并不关心子模块的内部开发流程细节。
通常不会把所有源码都放在同一个 Git 仓库中,此时可以通过 submodule的方式建立当前项目仓库 与 其他被调用的模块仓库的关系和连接。
使用 git submodule 功能时,主项目仓库并不会包含子模块的文件,只会保留一份子模块的配置信息及版本信息,作为主项目版本管理的一部分
命令 | 指令 | 说明 |
---|---|---|
初始化子模块 | git submodule init | 只在首次检出仓库时运行一次就行 |
更新子模块 | git submodule update | 每次更新或切换分支后都需要运行一下 |
添加子模块 | git submodule add [url] [path] | url为子模块的路径,path为该子模块在主仓库存储的路径 |
删除子模块 | .gitmodules | 补充说明 |
使用用例:
假设 project-main 表示主项目,而 project-sub-1 表示一个子模块项目。
我们想要在 project-main 中添加 project-sub-1,而又保持 project-sub-1自身独立的版本控制。
- project-main 的远程仓库地址为 https://github.com/username/project-main.git,
- project-sub-1 的远程仓库地址为 https://github.com/username/project-sub-1.git
1. 添加子模块
# 1. 主项目中添加一个子模块
git submodule add https://github.com/username/project-sub-1.git
此时项目仓库中会多出两个文件:.gitmodules 和 project-sub-1
- .gitmodules 描述子模块的相关信息,包含名称、放置目录、远端地址
- project-sub-1 保存的是子模块当前版本的版本号信息
git commit -m "add submodule xxx" push之后在主项目仓库中,会显示出子模块文件夹,并带上其所在仓库的版本号
# 添加子模块
git submodule add git://github.com/soberh/ui-libs.git src/main/webapp/ui-libs
2. 获取子模块代码
在主项目使用普通的 clone 操作并不会拉取到子模块中的实际代码,获取子模块代码有两种方式:
- git clone时,带上参数 --recurse-submodules
- 使用 git submodule update
git clone https://github.com/username/project-main.git --recurse-submodules
# 或者
git clone https://github.com/username/project-main.git
cd project-main
git submodule init
git submodule update
3. 子模块内容更新
-
对于子模块而言,并不需要知道引用自己的主项目的存在。对于自身来讲,子模块就是一个完整的 Git 仓库,按照正常的 Git 代码管理规范操作即可。
-
对于主项目而言,子模块的内容发生变动时,通常有三种情况:
- 当前主项目下子模块文件夹内的内容发生了未跟踪的内容变动。 (主要是直接改动子模块代码造成的)
- 当前项目下子模块文件夹内的内容发生了版本变化。
- 当前项目下子模块文件夹内的内容没变,远程子模块仓库有更新
## station1: 子模块文件夹内的内容发生了未跟踪的内容变动
在主项目中使用 git status 能够看到关于子模块尚未暂存以备提交的变更,
但是于主项目而言是无能为力的,使用 git add/commit 对其也不会产生影响.
通常需要进入子模块文件夹,按照子模块内部的版本控制体系提交代码 add/commit/push
## station2: 当前项目下子模块文件夹内的内容发生了版本变化
Station1提交完成后,主项目的状态则进入了情况2,
即当前项目下子模块文件夹内的内容发生了版本变化。
当子模块版本变化时,在主项目中使用 git status 查看仓库状态时,会显示子模块有新的提交.
此时可以在主项目中使用 git add/commit 将其添加到主项目的代码提交中,
实际的改动就是那个子模块 文件 所表示的版本信息。
通常当子项目更新后,主项目修改其所依赖的版本时,会产生类似这种情景的 commit 提交信息
## station3: 远程子模块仓库有更新
通常来讲,主项目与子模块的开发不会恰好是同时进行的。通常是子模块负责维护自己的版本升级后,推送到远程仓库,并告知主项目可以更新对子模块的版本依赖。
此时使用 git submodule update 也无能为力
上文提到,主项目可以使用 git submodule update 更新子模块的代码,
但那是指 当前主项目文件夹下的子模块目录内容 与 当前主项目记录的子模块版本 不一致时,会参考后者进行更新。
此时,需要让主项目主动进入子模块拉取新版代码,进行升级操作, 升级完就回到了station2
通常流程是:
cd project-sub-1
git pull origin master
当主项目的子项目特别多时,可能会不太方便,
此时可以使用 git submodule 的一个命令 foreach 执行:
git submodule foreach 'git pull origin master'
4. 删除子模块
git submodule deinit project-sub-1
git rm project-sub-1
git commit -m "delete submodule project-sub-1"
# 删除子模块 (不建议使用这种方法):(分4步走哦)
1) git rm --cached [path]
2) 编辑“.gitmodules”文件,将子模块的相关配置节点删除掉
3) 编辑“.git/config”文件,将子模块的相关配置节点删除掉
4) 手动删除子模块残留的目录
git release / tag
命令 | 说明 |
---|---|
git tag | 查看本地 tag |
git tag -r | 查看远端 tag |
git tag -a 标签名称 -m “说明” | 给当前commit 添加一个tag标签 |
git push origin 标签名称 | 推送到远端,并制定远端tag |
git tag -d 标签名称 | 删除本地tag |
git push origin --delete tag 标签名称 | 删除远端tag |
# 发布tag
git tag -a v3.0 -m "这是3.0版本" ## 本地的tag
git push origin v3.0 ##远程的tag
# 删除tag
git tag -d v1.1 //删除本地tag
git push origin :v1.1//删除远程tag
git push origin --delete tag V1.1 #功能同上
.gitignore
- .gitignore 可以控制git是否追踪某个文件或者文件夹,通常控制一些临时文件和编译文件等
- 注意:如果在创建.gitignore文件之前就push了某一文件,那么即使你在.gitignore文件中写入过滤该文件的规则,该规则也不会起作用,git仍然会对该文件进行版本管理。
/dir ##不追踪 dir文件夹
*.type ##不追踪某个文件夹下得某一类文件
/mtk/do.c ##过滤某个具体文件
!/mtk/one.txt ##追踪(不过滤)某个具体文件
Git 常用操作
基本常用操作
- git commit --amend 会打开git编辑器,重新编辑commit 提交注释
- git log -5 ##查看最近5次 commit摘要
- git log --pretty=oneline 只显示git log的commit id & 注释
- git relog ## 查看最近的commit_ID
如何免去每次push输密码
打开命令行终端输入
ssh-keygen -t rsa -C "your_email@example.com"
连续点击 Enter 键即可,中间提示输入密码时不要输入。
如何快速合并多次commit
方法 | 说明 | 特点 |
---|---|---|
git merge --squash | merge时合并commit | merge比较优雅 |
git rebase | 基于某次commit, squash多次commit | rebase可以通过一些参数更细粒度地控制合并的进程,比如-i参数可以让你在vim编辑器中选取合适的commit,你可以合并所有commit,也可以只合并其中的一些,而留下多个commit |
git reset --soft | 利用reset soft 回退到某次commit, 重新add之后的commit | reset更为简单粗暴一些,直接回滚commit,有时候rebase使用不当会出现一些难以解决的问题,此时reset可以派上用场 |
git checkout devel
git pull origin devel
# 基于最新的devel, 在feature_dev上开发, 进行了多次提交
git checkout -b feature_dev # 从最新devel创建feature_dev分支,并切换到该分支
git commit -m "fix bug 1" # 修复了bug1
git commit -m "fix bug 2" # 修复了bug2
#方法1:基于最新devel分支创建feature,merge feature_dev的时候,合并多条commit
git checkout devel
git pull origin devel
git checkout -b feature
git merge feature_dev --squash # 压缩合并feature_dev分支上的代码更新
git commit -a -m 'xxxx' #注意需要进行一次提交
git push origin feature # 推送到远程
# 方法2: 使用rebase
git rebase -i HEAD~N # N为合并的commit的数量
# 在rebase editor中选取被合并的commit,将其前面的字母置为s,按wq保存
# 方法3: 使用 reset soft 回滚
# git reset直接回滚到第一个commit之前的版本号,
# 此时更改的代码还在,但是commit全部消失了,重新add+commit一次即可
git reset --soft commit_id
git add
git commit -m " "
# 方法2、3推到远端需要强推
git push -f 强行推到远端分支即可。
如何找回误删的Branch or commit
- 使用
git reflog
找到误删的commit id - 使用
git fsck --full
找回
git log --pretty=oneline
ad2679d0027ecf588ef94208e9f79dd9b765615 commit_4
bd26792d0027ecf588ef94208e9f79dd9b765615 commit_3
cd26792d0027ecf588ef94208e9f79dd9b765615 commit_2
dd26792d0027ecf588ef94208e9f79dd9b765615 commit_1
# 这样操作后commit_4就被误删了
git reset --hard bd26792d0027ecf588ef94208e9f79dd9b765615
# 通过 reflog找回
git reflog
# bd26792 HEAD@{0}:
# ad26792 HEAD@{1}: commit_4
# bd26792 HEAD@{2}: commit_3
git branch recover-branch ad26792 # 找回误删的分支
git merge recover-branch # 并将其合到当前分支来
# 通过 git fsck
git fsck --full
dangling blob 3a14c01f3d8bc413f49d3eafb9586fe38eff50af
dangling commit 9b2ca07f8356fc67c5b0a879264c855e9ccc5196
dangling commit 272ec075a0088586a50a93b1118907c575a085f2
git branch recover-branch 9b2ca07f8356fc67c5b0a879264c855e9ccc5196
git merge recover-branch
如何在服务器上部署自己的Git 仓库
GitBook
Git 命令汇总
Cmd | Function |
---|---|
git clone -b 链接 | 下载指定分支的代码 |
git clone -C 链接 | 下载指定代码到指定位置 |
git branch | 查看本地分支 |
git branch -a | 查看远程分支 |
git remote | 查看远程主机 |
git remote -v | 查看远程主机的详细名称和地址 |
git branch -vv | 查看本地分支也远程分支的追踪关系 |
git branch branchName | 本地新建分支 |
git branch -d newBranch | 本地删除一个分支 |
git push origin branchName | 远程新建分支,并建立追踪关系 |
git checkout branchName | 本地切换到分支 |
git checkout -b branchName | 切换到分支branchName,如若没有就新建 |
git commit --amend | 会打开git编辑器,重新编辑commit 注释 |
参考文档: