【工具】Git

4/25/2022 tool

# 概述

2005 年,Linus 花了两周用 C 语言写成了 Git!(版本控制系统:分布式 VS 集中式)
重要概念:工作区 & 版本库(暂存区 stage、master、HEAD)

# 本地仓库

  • git 的安装

    git config --global user.name "Your Name"
    git config --global user.email "email@example.com"
    
    1
    2
  • git 的基本使用

    mkdir directory
    cd directory
    pwd        // 打印当前目录
    git init
    ls -ah     // 查看当前目录下的文件,包括隐藏文件
    touch readme.txt
    git add readme.txt   // 可以多次add,一次commit
    git commit -m "write a readme file"
    git status
    git diff readme.txt   // 查看具体的修改
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  • 查看版本日志

    git log   // 查看当前版本之前的历史提交记录(穿越过去)
    git log --pretty=oneline    // 简单输出
    git reflog    // 查看所有的历史提交记录(重返未来)
    
    1
    2
    3
  • 版本回退

    git reset --hard HEAD^    // 回退到上一个版本
    cat readme.txt   // 查看文件内容
    git reset --hard commit_id    // 版本号不用写全
    
    1
    2
    3
  • 工作区/版本库

    git diff HEAD -- readme.txt   // 查看工作区和版本库里面最新版本的区别
    git checkout -- readme.txt    // 丢弃工作区的修改(两种情况:readme.txt是否已在暂存区,最近的状态)
    git reset HEAD readme.txt     // 将add进暂存区的文件,重新放回工作区
    
    1
    2
    3
  • 删除文件

    git add test.txt
    git commit -m "add test.txt"
    rm test.txt
    git status
    git rm test.txt
    git commit -m "remove test.txt"git checkout -- test.txt   // 把误删的版本恢复到版本库中的最新版本,即用版本库里的版本替换工作区的版本
    
    1
    2
    3
    4
    5
    6
    7
    8

# 远程仓库

  • 远程仓库连接

    git remote add origin git@github.com:xxx/xxx.git   // 添加并绑定远程仓库,远程库的名字就是origin
    git push -u origin master    // 把本地库的所有内容推送到远程库(第一次推送master分支时,加-u的作用:关联本地和远程的master分支)
    git push origin master       // 往后的推送
    
    1
    2
    3
  • 断开与远程仓库的连接

    git remote -v    // 查看远程库信息
    git remote rm origin    // 解除本地和远程的绑定关系
    
    1
    2
  • 从远程库克隆

    git clone git@github.com:xxx/xxx.git    // 创建远程库,并克隆到本地
    
    1

# 分支管理

注意:HEAD 指向的是当前分支。推荐使用分支完成某个任务,合并后再删除。

  • 分支操作—checkout

    git checkout -b dev   // 创建并切换到分支dev,相当于以下两条命令
    git branch dev
    git checkout dev
    git branch    // 列出所有分支,当前分支前加*
    ...... Do something on dev ......
    git checkout master   // 切换回主分支
    git merge dev   // 把dev分支的工作成果合并到master分支,快进模式(Fast-forward)
    git branch -d dev   // 删除dev分支
    git branch
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  • 分支切换—switch

    git switch -c dev     // 创建并切换到分支dev
    git switch master     // 切换到主分支
    
    1
    2
  • 冲突解决

    git merge dev   // 合并dev和master分支,发生冲突
    git status      // 查看发生冲突的文件
    cat readme.txt  // 修改冲突文件,<<<<<<<=======>>>>>>>
    git add readme.txt
    git commit -m "conflict fixed"  // 再次提交
    git log --graph --pretty=oneline --abbrev-commit    // 查看分支合并情况
    git branch -d dev
    
    1
    2
    3
    4
    5
    6
    7
  • 分支管理

    git switch -c dev
    git add readme.txt
    git commit -m "add merge"
    git switch master
    git merge --no-ff -m "merge with no-ff" dev
    git log --graph --pretty=oneline --abbrev-commit
    
    1
    2
    3
    4
    5
    6

    通常,合并分支时,如果可能,Git 会用 Fast forward 模式,但这种模式下,删除分支后,会丢掉分支信息。
    如果要强制禁用 Fast forward 模式(--no-ff),Git 就会在 merge 时生成一个新的 commit,这样,从分支历史上就可以看出分支信息。

  • Bug 分支

    考虑场景:正在 dev 分支上进行开发,突然接到立即修复 bug 的任务,但工作尚未完成不能提交。

    git stash   // 隐藏当前工作区,等以后恢复现场后继续工作
    git status   // 干净的工作区
    在master分支上,创建分支来修复bug
    git checkout master
    git checkout -b issue-101   // 创建并切换到临时分支
    ...... fix the bug, add, commit ......
    git switch master
    git merge --no-ff -m "merged bug fix 101" issue-101   // 合并bug,并删除issue-101分支
    git switch dev     // 继续回到dev分支干活
    git status
    git stash list     // 列出保存的工作区现场
    恢复工作现场
    git stash apply & git stash drop   // 恢复并删除stash内容
    git stash pop
    git stash apply stash@{0}    // 恢复指定的stash
    注意:到目前为止,master上的bug被修复,而dev是更之前的分支,其上也存在相同的bug,且还未被修复。
    git branch  // dev 分支
    git cherry-pick 4c805e2   // 复制一个特定的提交到当前分支(4c805e2为bug修复的提交id),自动为dev分支做了一次提交
    也可以直接在dev分支上修复bug,再切回master“重放”这个修复过程,依旧需要保存现场。
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
  • Feature 分支

    每添加一个新功能,最好新建一个 feature 分支,在上面开发,完成后合并,最后删除该 feature 分支。

    git branch -D feature  // 强行删除一个没有被合并过的分支
    // 其他操作跟Bug分支类似
    
    1
    2
  • 多人协作

    git remote     // 查看远程库的信息
    git remote -v    // 查看远程库的详细信息
    git push origin master    // 向远程库推送主分支(主分支要时刻与远程同步)
    git push origin dev       // 向远程库推送其他开发分支(开发分支也要时刻与远程同步)
    bug分支只用于在本地修复bug,没必要推到远程;
    feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
    git checkout -b dev origin/dev   // 创建远程origin的dev分支到本地
    git add env.txt
    git commit -m "add new env"
    git push origin dev
    发现提交的新修改存在冲突
    git branch --set-upstream-to=origin/dev dev   // 指定本地dev分支与远程origin/dev分支的链接
    git branch --set-upstream branch-name origin/branch-name
    git pull    // 抓取origin/dev上的最新提交到本地
    手动解决冲突,add,commit,最后push
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
  • Rebase:可以把本地未 push 的分叉提交历史整理成直线

    git rebase    // 把分叉的提交历史“整理”成一条直线,看上去更直观
    git log --graph --pretty=oneline --abbrev-commit   // 本地提交记录是一条直线
    git push origin master
    git log --graph --pretty=oneline --abbrev-commit   // 本地和远程提交记录都是一条直线
    
    1
    2
    3
    4

# 标签管理

标签,即版本库的一个快照,发布版本时通常会在版本库中打一个标签。

  • 创建标签

    git branch
    git checkout master    // 在主分支上打标签
    git tag v1.0      // 为最新的提交打标签
    git tag           // 查看所有标签(按字母排序)
    git log --pretty=oneline --abbrev-commit      // 查看提交历史
    git tag v0.9 f52c633     // 为指定提交打标签
    git show v0.9    // 查看标签信息
    git tag -a v0.1 -m "version 0.1 released" 1094adb  // 创建带有说明的标签
    
    1
    2
    3
    4
    5
    6
    7
    8
  • 操作标签

    git tag -d v0.1     // 删除标签,标签存储在本地
    git push origin v1.0     // 推送某个标签到远程
    git push origin --tags   // 一次性推送全部尚未推送到远程的本地标签
    删除远程标签
    git tag -d v0.9   // 本地删除
    git push origin :refs/tags/v0.9    // 同步远程
    登录GitHub,查看标签是否删除
    
    1
    2
    3
    4
    5
    6
    7

# GitHub 和 Gitee

  • 如何参与开源项目?

    • Fork 某个开源项目
    • git clone git@github.com:xxx/xxx.git // 从自己的账号下 clone(避免没有推送权限)
    • 修复 bug 或新增功能后,在 GitHub 上发起一个 pull request,代码贡献
  • Gitee 使用

    git remote -v
    git remote rm origin
    git remote add origin git@gitee.com:xxx/xxx.git
    git remote rm origin
    git remote add github git@gitee.com:xxx/xxx.git
    git remote add gitee git@gitee.com:xxx/xxx.git
    git remote -v
    git push github master
    git push gitee master
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# Git 自定义

git config --global color.ui true    // 让Git显示颜色,会让命令输出看起来更醒目

https://github.com/github/gitignore     // 配置文件
忽略文件:.gitignore,把要忽略的文件名填进去。要放到版本库
# Windows:
Thumbs.db
ehthumbs.db
Desktop.ini

# Python:
*.py[cod]
*.so
*.egg
*.egg-info
dist
build

# My configurations:
db.ini
deploy_key_rsa

# 不排除.gitignore和App.class:
!.gitignore
!App.class

git add -f App.class   // 强制添加到Git
git check-ignore -v App.class   // 查看忽略文件中的哪个规则使添加失效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 场景举例

  • case 1
    • 描述:在本地修改完成已 push 至远程后,想要撤销这次的 push。(本地修改不变/回退到上个版本,远程退回到上次 push 的版本)
    • 解决:reset 不产生新 commit,只是改变当前 HEAD 指向的 commit
      • 不删除工作空间改动代码,撤销 commit,不撤销 git add:git reset --soft 版本号
      • 删除工作空间改动代码,撤销 commit,撤销 git add:git reset --hard 版本号
      • 最后强制提交当前版本,以撤销仓库远程版本号:git push origin master -–force
  • case 2
    • 描述:依次向远程提交了三个版本(版本 1,2,3)后,突然发现版本 2 不行,想要撤销版本 2,又不想影响版本 3 的提交。
    • 解决:revert
  • case 3
    • 描述:批量修改 commit 注释
    • 解决:rebase
  • case 4
    • 描述:同步远程代码
    • 解决:fetch vs pull( git pull = git fetch + git merge/rebase )
  • case 5
    • 描述:修改分支名
    • 解决:分支重命名 (opens new window)
      • 切换到旧分支:git checkout old_branch
      • 更新旧分支与远程分支一致:git pull origin old_branch
      • 重命名分支:git branch -m old_branch new_branch
      • 将本地新分支推送到远程:git push --set-upstream origin new_branch
      • 将远程旧分支删除:git push origin --delete old_branch
  • case 5
    • 描述:删除分支
    • 解决:--delete/-d
      • 删除本地分支:git branch -d <branch_name>
      • 删除远程分支:git push origin --delete <branch_name>

# 参考

Last Updated: 10/8/2022, 2:29:52 PM