Published on

Git全栈操作指南:仓库管理、分支策略与高级工作流实战

Authors
  • avatar
    Name
    Liant
    Twitter

git常用操作指令

一、仓库

  • 克隆
git clone <url>

二、分支

  • 查看分支
  • 查看本地分支:无参数
  • 查看远程分支:-r
  • 查看全部分支:-a
  • 查看本地分支与追踪分支:-vv
git branch {-r|-a|-vv}?
  • 基于当前分支创建新分支
git branch <new-branch>
  • 基于当前分支创建新分支,并切换至新分支
git checkout -b <new-branch>
  • 基于其他分支创建新分支,并切换至新分支
git checkout -b <new-branch> <other-branch>
  • 切换到已有分支
git checkout <branch>
  • 删除分支(已合并的)
git branch -d <branch>
  • 删除分支(未被合并的)
git branch -D <branch>
  • 合并分支
git merge <branch>
  • 同步远程分支状态
git remote prune origin
  • 同步远程分支最新commit(缓存信息,不会同步代码)
git fetch <branch>?

三、工作区、暂存区、本地仓库、远程仓库操作

images/git-area-tree.png
  • workspace: 直接写好的代码,以文件形式存在硬盘上的,其实就是保存在workspace工作区
  • index/stage: git add之后会存入stage/index暂存区
  • repository: git commit之后会存入repository本地仓库
  • remote: git push 之后会存入remote远程仓库

将工作区更改推入暂存区

# 指定文件或文件夹
git add <fileName> <fileName> ...
# 当前文件夹下所有更改
git add .
  • 将暂存区文件退回
# 退回后恢复到暂存区的状态,会舍弃工作区更改
git restore <file>
# 只是将文件追踪从暂存区退回,工作区更改不会覆盖
git restore --staged <file>
  • 将暂存区文件推入本地存储库
git commit -m <message>
  • 查看commit日志
# 全量查看
git log
# 显示某文件的提交日志
git log -p <file>
# 根据提交信息中的关键字查找
git log --grep=<keyword>
# 显示指定作者的提交信息
git log --author=<author>
# 查看某笔commit的信息
git show <commitID>
  • 查看工作区文件状态
git status
# sb参数显示分支追踪信息
git status -sb
images/git-status.jpeg
> - **Untracked files**: 更改的文件
> - **Changes to be committed**: 修改的文件
> - 如果本地分支关联了远程分支,会展示与远程origin/<branch>的commit差距数
images/git-status-sb.jpeg
> - **##**: 与远程关联分支origin/<branch>的commit差距数
> - **A**: 新增文件
> - **D**: 删除文件
> - **M**: 修改文件
> - **??**: 未跟踪文件
  • 快速清空工作区更改

只能清除已被追踪,且没有加入暂存区的更改。新增文件无法清除(请使用clean)。

git checkout .
  • 未追踪文件
# 显示
git clean -n
# 清除文件
git clean -f
# 清除目录及文件
git clean -df
  • git stash储藏与恢复

想象成git仓库中有一片独立的内存空间,专门负责存储stash推送的文件与记录。stash后会生成一条记录,并推送到列表记录。允许多次推送,git stash list可以看到列表记录。stash是独立的存储和记录,所以它不会受到分支的影响。一笔改动想同步多个分支时,可以stash后,在目标分支下stash apply。代码改动处理弄错了分支,可以stash后,在正确分支下stash pop。重要提示:stash无法存储未被追踪的文件(比如新增的文件)。如果需要stash新增文件类,需要先add该文件。

# 储藏工作区更改的文件
git stash
# 储藏工作区更改的文件,并添加描述信息
git stash save <message>
# 恢复存储,不加stash@{x}默认为第0条记录(即最新推入的stash)
git stash apply <stash@{x}>?
# 恢复存储,不加stash@{x}默认为第0条记录(即最新推入的stash),并删除stash list记录
git stash pop <stash@{x}>?
# 查看储藏列表
git stash list
# 清除所有stash
git stash clear
  • commit与分支。
> - 每一笔commit代表一个节点,可以理解为一次"游戏存档"
> - 分支则是一条串联多个commit的链
> - 每一个分支在git仓库系统中会产生一个独有的指针,命名为分支名称,比如指针master代表本地分支master
> - 远程关联分支则会产生一个origin/<分支名称>的指针,比如指针origin/master代表远程分支master
> - 本地仓库中永远存在一个HEAD指针,代表当前代码的位置(一定是指向该分支链上最新的一笔commit)
images/commit.png
images/commit-tree.jpg

常见的指针包括:

  • master: 本地master分支
  • origin/master: 远程master分支
  • test: 本地test分支
  • origin/test: 远程test分支
  • HEAD: 当前代码位置
images/git-log.jpeg
  • 回退 reset

回退只能以历史中某次commit为主,即读取"游戏存档"。回退是直接舍弃这个"存档"之后的所有文件更改。只要记得任意的commitID,就可以回到这笔提交。

# 重置暂存区(已add未commit,可以配合checkout/clean分步清除要舍弃的修改)。
git reset
# 重置暂存区和工作区(相当于git reset && git checkout .)
git reset --hard
# 恢复本分支到某次提交,重置工作区与暂存区(本地的改动和暂存都将被舍弃)
git reset --hard <commitID>|HEAD^|HEAD~1
# 恢复本分支到某次提交(本地的改动和暂存保留)
git reset --soft <commitID>
# 恢复本分支到某次提交,重置暂存区(本地的改动会保留,暂存区的改动舍弃)
git reset --mixed <commitID>
# 查看操作日志
git reflog
  • 重做 revert

重做只会舍弃某一笔commit提交的文件改动。重做是新添加一笔与原commitID改动相反的改动,并提交一笔最新的commit记录。当前适用场景为:生产分支合并了多笔commit后,想回退一笔不是最新的commit。如果reset的话,会导致之后提交的commit也回退了。这时候可以revert这一笔commit,达到回退。注意事项1:如果生产不是用的扁平化合并,想重做的更改可能不止一笔commit,这时候重做需要一笔一笔处理,并且冲突性会很强烈。(所以要求生产的pull request一定要使用扁平化合并的方式)注意事项2:由于revert是以新commit来覆盖重做commit的提交,所以想revert后恢复,就要revert相对应的revert提交的那笔commit。

四、合并、变基、扁平化、解决冲突

  • rebase与merge详细说明
  • 扁平化合并:只会将开发分支的改动代码拉取过来,不会同步开发分支的commit
  • 扁平化合并手动模式:需要解决冲突后,自行add和commit
  • 普通合并模式:会将所有commit日志推到生产分支
# 合并分支
git merge <branch>
# 只合并某笔commit
git cherry-pick <commitID>
# 变基合并
git rebase <branch>
# 合并冲突解决完成后
git add .
git rebase --continue
# 退出变基合并
git rebase --abort
# 扁平化合并(pull request模式)
git merge --squash <branch>
git add .
git commit -m <message>

参考