git的常用操作和场景

这里只记录一些常用的操作或者工作中遇到一些场景。

应当统一几个概念

workspace（工作区）：即你本地环境

staging area（暂存区 / 缓存区）：输入命令 git add 文件路径，该文件的改动就放到了这个暂存区

local repository（版本库或本地仓库）：输入命令 git commit -m "此次修改的描述"，改动就被放到了本地仓库

remote repository（远程仓库）：输入命令git push，改动就被放到远程仓库，如 github, gitlab 等

他们之间的联系如下图所示

sequenceDiagram participant A as 工作区 participant B as 暂存区 participant C as 本地仓库 participant D as 远程仓库 A->>B: git add <file> B->>C: git commit -m "message" C->>D: git push D-->>C: git reset --soft HEAD^ C-->>B: git restore --staged <file> B-->>A: git restore <file>或git checkout <file>

下面是可以配置的常用的 alias（别名）

Copy
alias.amd=commit --amend --no-edit
alias.am=commit --amend
alias.br=branch --sort=-committerdate
alias.ci=commit
alias.co=checkout
alias.cp=cherry-pick
alias.df=diff
alias.drop=stash drop
alias.pci=!git fetch origin master && git rebase origin/master && git push
alias.la=log --oneline --decorate --graph --all
alias.last=log -1 HEAD --stat
alias.ls=log --graph --pretty=format:'%Cred%h%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset %C(yellow)%D%Creset' --abbrev-commit
alias.lg=log --stat
alias.pl=pull --rebase origin master
alias.pop=stash pop
alias.pr=pull --rebase --recurse-submodules
alias.rc=rebase --continue
alias.ri=rebase -i HEAD~10
alias.root=rev-parse --show-toplevel
alias.save=stash save
alias.sl=stash list
alias.st=status
alias.sup=submodule update --init --recursive
alias.unstage=reset HEAD --

另外，文章里提及的命令虽然已经过测试，但一定请先试了效果后再实际应用到工作生产环境中，以防造成无法弥补的后果。
所有带有<>的说明它是一个变量，是根据需要替换的，替换的时候命令中不用包含这个符号。

快速切换到上一个分支

Copy
git co -

删除本地分支

Copy
git branch -d <branch-name>

删除远程分支

Copy
git push origin --delete <branch-name>

删除远程已删除本地还存在的分支

Copy
git remote prune origin

重命名本地分支

Copy
git branch -m <new-branch-name>

还原 commit (以新增 commit 的形式)

Copy
git revert <commit-id>

回到某个 commit，并删除之后的 commit

和 revert 的区别是，reset 或抹去 commit-id 后的所有 commit

Copy
git reset <commit-id> # 默认--mixed参数

# --mixed: 不删除工作空间改动代码，撤销commit，并且撤销git add .
# --soft: 不删除工作空间改动代码，撤销commit，不撤销git add .
# --hard: 删除工作空间改动代码，撤销commit，撤销git add .
git reset --mixed HEAD^ # 回退至上个版本，它将重置HEAD到当前的前一个commit,并且重置暂存区以便和HEAD相匹配，但是也到此为止。工作区不会被更改

git reset --soft HEAD~3 # 回退至三个版本之前，只回退了commit的信息，暂存区和工作区与回退之前保持一致。如果还要提交，直接commit即可

git reset --hard <commit-id> # 彻底回退到指定commit-id的状态，暂存区和工作区也会变为指定commit-id版本的内容

保存当前修改但是不提交

Copy
git stash

保存当前修改，包括 untrack（新增的）文件

Copy
git stash -u

列出所有 stash

Copy
git stash list

回到某个 stash 状态

Copy
git stash apply <stash@{n}> # 修改这个n

回到最近一个状态，并从 stash 列表删除它

Copy
git stash pop

删除所有 stash

Copy
git stash clear

应用某个 stash 里的某个文件修改

Copy
git diff <stash@{n}> -- <file-path> # 应用前可以先看下diff
git co <stash@{n}> -- <file-path>

列出所有 track 文件

Copy
git ls-files -t

列出所有 untrack 文件

Copy
git ls-files --others

删除 untrack 文件

clean 命令可以用来删除新建的文件。如果不指定文件文件名，则清空所有工作的 untracked 文件。注意两点:

clean 后，删除的文件无法找回

不会影响 tracked 的文件的改动，只会删除 untracked 的文件

Copy
git clean <file-path> -f # 其实还不如手动删除

强制删除 untrack 目录

Copy
git clean <directory-name> -df # 其实就是把新建的目录及文件删除了，只不过找不回

清除 gitignore 中记录的文件

Copy
git clean -X -f

显示 A 分支有而 B 分支没有的 commit

Copy
git log A ^B

展示任意分支某一文件内容

Copy
git show <branch-name>:<file-name>

根据 commit message 内容关键词查找 commit

Copy
git log --all --grep='<finding-message>'