git操作
记录git的基础/常用操作,以备查阅
参考/推荐
基础操作
基础操作
git各个区域及基础操作:
注意: pull = fetch + merge 即拉取远程仓库的内容并合并到本地仓库
遇到的小问题
有时候可能会因为种种原因无法连接到remote,这时可以尝试以下方法:
查看git的ssh连接状态, 可以使用ssh -v -T
命令:
1
2
3
4
$ ssh -v -T # 查看ssh连接状态, -v: verbose, -T: 不分配伪终端
$ ssh -vT # 与上面命令等价
$ ssh ... -v # 使用verbose模式运行其他git命令
设置git代理:
1
2
3
4
5
6
7
8
9
10
11
# 一次性代理
git -c http.proxy="https://1.2.3.4:1234" clone <repo-url>
# 设置全局代理
git config --global http.proxy https://1.2.3.4:1234
git config --global https.proxy https://1.2.3.4:1234
# 设置socks5代理
git config --global http.proxy socks5://1.2.3.4:1234
# 只对github.com设置代理
git config --global http.https://github.com.proxy http://1.2.3.4:1234
git config --global https.https://github.com.proxy http://1.2.3.4:1234
git config --global http.https://github.com.proxy socks5://1.2.3.4:1234
git初始化
1
2
3
4
5
$ git init # 初始化仓库
$ git clone # 从remote克隆一个仓库到本地
$ git add . # 把所有文件添加到staging area
$ git commit . # 将staging area 中所有内容提交到 local repository
$ git commit . -m <message> # 将staging area 中所有内容提交到 local repository,且快速添加信息
加入暂存区
1
2
3
$ git add <file> # 将指定文件添加到暂存区
$ git add . # 将所有文件添加到暂存区
$ git add -p # 交互式按块添加文件到暂存区(逐个文件交互式添加)
状态查看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ git status # 查看当前状态
$ git log # 查看日志
$ git shortlog # 查看短日志
$ git reflog # 查看历史操作记录
$ git reflog -2 # 查看最近两次操作记录
$ git reflog -2 <branch-name> # 查看branch-name分支的最近两次操作记录
$ git diff # 查看工作区与暂存区的差异
$ git blame <file> # 以列表形式查看指定文件的历史修改记录
$ git show <commit-id> # 查看指定commit-id的提交记录
$ git show <commit-id> <file> # 查看指定commit-id的指定文件的提交记录
$ git show HEAD~2 # 查看倒数第二次提交记录
$ git show <tag-name> # 查看指定tag的提交记录
分支操作
1
2
3
$ git checkout -b <new-branch-name> # 创建新分支
$ git checkout <branch-name> # 切换(检出)到指定分支
$ git checkout master^^ # 切换到master分支的上上个版本
1
2
3
4
$ git branch # 查看本地所有分支
$ git branch -r # 查看remote上的分支
$ git branch -a # 查看所有(本地+remote)分支
$ git branch -d <branch-name> # 删除指定分支
1
2
$ git merge <branchA> # 将branchA合并到当前分支
# 注意: merg时可能会出现分支冲突,这时需要手动add 有冲突的文件
switch指令专门用来简化分支移动操作:
1
2
$ git switch <branch-name> # 切换到指定分支
$ git switch -c <new-branch> # 创建并切换到新分支
回退版本
1
2
3
4
$ git reset [--hard] HEAD^ # 回退一个版本
$ git reset [--hard] HEAD^^ # 回退两个版本
$ git reset [--hard] HEAD~n # 回退n个版本
$ git reset [--hard] <commit-id> # 回退到指定版本
reset指令的三种模式:
- –soft: 仅仅在本地移动HEAD指针,不改变暂存区和工作区
- –mixed: 默认模式,移动HEAD指针和暂存区,不改变工作区
- –hard: 移动HEAD指针、暂存区和工作区
reset也可以用于回退后又想恢复的情况,可以通过git reflog
查看历史操作记录,然后通过git reset --hard <commit-id>
恢复:
1
2
$ git reflog # 查看历史操作记录
$ git reset --hard <commit-id> # 恢复到指定版本
文件删改
1
2
3
4
$ git rm <file> # 删除文件
$ git mv <old-file> <new-file> # 重命名文件
$ git checkout -- <file> # 撤销工作区的修改
$ git diff # 查看工作区与暂存区的差异
远程操作
在 Git 中,origin 是默认的远程仓库的名称。当你克隆一个远程仓库到本地时,Git 会自动创建一个名为 origin 的远程仓库别名,指向原始的远程仓库。
1
2
3
4
5
6
7
$ git remote add origin <remote-url> # 添加远程仓库
$ git -T <remote-url> # 测试远程仓库是否连接成功
$ git remote -v # 查看远程仓库
$ git push origin <branch-name> # 将本地HEAD所在节点分支推送到远程仓库<branch-name>分支
$ git pull origin <branch-name> # 从远程仓库拉取<branch-name>分支到本地HEAD所在节点分支(工作区)
$ git push origin --delete <branch-name> # 删除远程仓库<branch-name>分支
$ git merge origin/<branch-name> # 将远程仓库<branch-name>分支合并到本地HEAD所在节点分支
HEAD指针
HEAD 指针是一个指向当前所在分支的指针,它通常指向最近一次提交的结果。
我们最好要避免出现 HEAD 指针指向一个分离状态,这种状态下,HEAD 指针不再指向任何分支,而是直接指向一个提交。摆脱分离:git switch <branch-name>
。
1
2
$ git checkout HEAD <file> # 撤销工作区的修改,相当于将HEAD指针的内容覆盖到工作区
$ git reset HEAD <file> # 撤销暂存区的修改,相当于将HEAD指针的内容覆盖到暂存区
标签操作
1
2
3
$ git tag # 查看所有标签
$ git tag <tag-name> # 创建标签,默认为HEAD所在节点
$ git checkout tags/tagname # 切换到指定tag的分支
冲突解决
一般情况下,冲突解决的步骤如下:
git pull
拉取远程仓库的内容git status
查看冲突文件;git diff
查看冲突文件的具体内容- 手动解决冲突文件:
- 对于冲突文件,会有类似如下的标记:
1 2 3 4 5
<<<<<<< HEAD 本地仓库的内容 ======= 远程仓库的内容 >>>>>>> 123456
我们在解决冲突时,需要手动删除标记(即
<<<<<<< HEAD
、=======
、>>>>>>> 123456
),并保留需要的内容。或者使用Vscdoe等IDE的冲突解决工具。
- 对于我们在
git pull
后一些本地分支上的文件因为pull
而丢失,我们可以使用git checkout -- <file>
来撤销工作区的修改,然后再手动解决冲突文件。可以遵循以下步骤:1 2 3 4 5 6
$ git log # 查看提交记录的hash 或者使用git reflog查看历史操作记录 $ git show <commit-hash> # 查看提交记录的详细信息 $ git checkout <commit-hash> -- <file> # 恢复指定文件 $ git add <file> # 添加冲突文件 $ git commit -m "恢复丢失的文件" # 提交冲突文件 $ git push # 推送到远程仓库
- 对于冲突文件,会有类似如下的标记:
git add <file>
添加冲突文件git commit -m <message>
提交冲突文件git push
推送到远程仓库
添加子模块/子仓库
子模块是一个独立的仓库,可以被添加到主仓库中。子模块的内容可以独立于主仓库的内容进行更新和修改。
git submodule
命令用于管理包含其他Git仓库的项目。
初始化子模块
1
2
3
4
5
6
7
8
9
$ git submodule int # 添加子模块
# 常使用以下流程初始化子模块:
$ git clone <repo-url> # 克隆子模块仓库
$ cd <submodule-dir> # 进入子模块目录
$ git submodule init # 初始化子模块
# 或者使用以下命令直接add并初始化子模块:
$ git submodule add <repo-url> [<submodule-dir>] # 添加子模块
更新子模块
1
2
3
$ git submodule update # 更新子模块
$ git submodule update --remote # 更新子模块并拉取远程仓库的内容
$ git submodule update --recursive --remote # 更新子模块并递归更新子模块的子模块
添加子模块
1
$ git submodule add <repo-url> [<submodule-dir>] # 添加子模块
删除子模块
1
2
$ git submodule deinit <submodule-dir> # 删除子模块
$ git rm <submodule-dir> # 删除子模块
查看子模块
1
2
$ git submodule # 查看子模块
$ git submodule status # 查看子模块状态
使用.gitmodules
文件
.gitmodules
文件用于指定子模块的地址、路径等信息。
1
2
3
[submodule "submodule-name"]
path = submodule-path
url = submodule-url
相关配置文件
.gitignore
.gitignore 文件用于指定不需要加入版本控制的文件,比如编译生成的文件、日志文件、临时文件等。
# 忽略所有 .a 结尾的文件
*.a
# 但是 lib.a 除外
!lib.a
# 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目录下的所有文件
build/
# 忽略 doc/notes.txt 文件,但不忽略 doc/server/arch.txt 文件
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
.gitattributes
.gitattributes 文件用于指定文件的属性,比如文本文件、二进制文件、换行符等。
# 设置所有文件以文本文件处理
* text=auto
# 设置所有文件以二进制文件处理
*.bin binary
# 设置所有文件以文本文件处理,且换行符为LF(即\n)
* text eol=lf
# 设置所有文件以文本文件处理,且换行符为CRLF(即\r\n)
* text eol=crlf
.gitmodules
.gitmodules 文件用于指定子模块的地址、路径等信息。
[submodule "submodule-name"]
path = submodule-path
url = submodule-url
git Flow工作流
- master 分支
- 永远保持稳定和可发布的状态。
- 每次发布一个新的版本时,都会从 develop 分支合并到 master 分支。
- hotfix 分支
- 用于修复紧急问题。
- 从 master 分支创建,修复完成后合并回 master 和 develop 分支,并打上版本标签。
- 命名规范:hotfix/hotfix-name。
- release 分支
- 用于准备新版本的发布。
- 从 develop 分支创建,进行最后的测试和修复,然后合并回 develop 和 master 分支,并打上版本标签。
- 命名规范:release/release-name。
- develop 分支
- 用于集成所有的开发分支。
- 代表了最新的开发进度。
- 功能分支、发布分支和修复分支都从这里分支出去,最终合并回这里。
- feature 分支
- 用于开发新功能。
- 从 develop 分支创建,开发完成后合并回 develop 分支。
- 命名规范:feature/feature-name。