Dashuang Du.
Dashuang Du.

study and practice, years of it.

git workflow & 常用命令

2018, May 20    

好处

  • 版本控制
  • 代码备份
  • 比较不同版本的代码,找到问题
  • 。。。

流程

  • master branch 是可以发布的代码。master 不做开发,只用来 merge 其他 branch。
  • 所有的开发都应在 branch 里进行,开发完成并测试成功后,提交 Pull Request 做 code review,最终 merge 到 master 里。
    • 开发新功能,修复 bug 等等的操作应该创建 branch,单独提交。不要与以前的 branch 混在一起。
    • 所有 branch 可以 push 到 bitbucket,做代码备份。
  • 同步分支时,不要使用 git pull (因为会默认做 git fetch 和 merge)。先使用 git fetch 来确定是否与远端同步,然后再决定运行 merge 或者 reset --hard
  • 如果本地分支与远端已经分道扬镳,然后我们需要把本地与远端同步,放弃本地的修改,可以运行:
    • git reset –hard origin/branch # 如果远端已经与本地不在一条开发线路上。通过 reset 与远端同步。
  • 以在个人分支 dev_branch 下开发为例:
    • 每天与远端同步 master branch。特别是在提交 Pull Request 之前。运行:
      • git co master
      • git fat
      • git merge origin/master # 如果远端有更新,同步
    • 本地 master 同步更新后,对正在开发的 branch 进行 rebase,与本地 master 同步。 运行
      • git co dev_branch
      • git rebase master 或者 git rebase -i master 对本地的 commit 进行清理
      • git push origin/dev_branch -f # 此时需要 force push 来覆盖远端。
  • PR 和 code review
    • 尽量保持每个 PR 简短,便于进行 code review。
    • 发出 PR 后,需要在 1-2 天内完成 code review,这也需要 PR 尽量简短。
  • 每一次 commit 之前,再次 review 代码更改
    • git diff 显示 commit 做的所有修改,确定是否正确。
    • git ci -v 写 commit message
  • commit message
    • 如果可以用英文说明,使用英文。
    • 标题要简单明了,说明本次改动。
      • git ci -m ‘fix typo in variable name’ # 简单的修改,一行标题足够。
    • 复杂的 commit 除了写标题,还要写明为什么。例如:
      • git ci -v # 开始复杂的 commit message

           修复处理支付宝和微信支付超时,进行退单失败的情况
           -- 此处要多出空行,和主题区分。否则会与标题一起显示
           支付宝支付成功后,不可以进行订单撤销,这时,返回支付成功结果。微信支付
           成功后,仍然可以进行订单撤销。两种支付不同方式处理。
        

如何使用

fetch

  • 与远端分支同步,运行:

      git fetch --all --tags
    

log

  • 以单行形式,显示最近 10 个 commit

      git log --oneline -10
    
  • 显示所有 commit 的详细内容

      git log -p
    
  • 显示某个文件的更新内容

      git log -p  filename
    
  • 显示某个 commit 的详细内容

      git show 2c051d4
    

删除

  • 把已经删除的文件 stage (使用系认自带的命令删除的情况下)。

      git rm $(git ls-files --deleted)
      git commit -m 'delete files'
    
  • 不从硬盘里删除文件,只是告诉 git 不在跟踪某些文件。如果以为 commit 了某些文件,可以使用这个方法操作。然后把这些文件加入 .gitignore 里,告诉 git 不再考虑这些文件。

      git rm --cached filename1 filename2
      git commit -m 'dont track these files'
    
  • 删除目录和目录下的内容

      git rm -r directory
    

更名

git mv  old new   # 效果和  git rm --cached orig; mv orig new; git add new  一样。

分支

  • 列出已有分支

      git branch
    
  • 新建分支 (基于当前代码) 并切换到这个分支里

      git checkout -b  branch_name
    
  • 显示分支的某个文件内容

      git show branch_name:filename
    

reset

  • 把当前没 commit 的更新扔掉(仍停留在当前的 commit)

      git reset --hard   # 和 git reset --hard HEAD 一样
    
  • 把当前没 commit 的更新扔掉,回到上一个 commit

      git reset --hard HEAD^
    
  • 保留未 commit 的内容,把 staged 的文件 (例如 git add, git rm 等等)恢复为 unstaged 的状态。

      git reset
    
  • 把最新 commit 的文件重新恢复到 unstaged 的状态。使用场景:commit 后需要修改 commit 消息。或者有一个小的修改忘记加了。注意:如果已经 push 到远端,再次 push 时则需要 force push 才可以覆盖。

      %git log --oneline -2
      e1bc091 p
      f0a44be z
    	
      %git reset HEAD~1
      On branch master
      Untracked files:
        (use "git add <file>..." to include in what will be committed)
    	
          p
    	
      nothing added to commit but untracked files present (use "git add" to track)
    	
      % git log --oneline -2
      f0a44be z
    	
    
  • 如何不管当前分支的修改,而恢复到远端。使用场景:比如当一个分支被搞坏时,需要从头再来。

      git reset --hard origin/REMOTE_BRANCH_NAME
    
  • 如果正在某个分支里编辑,忽然需要切到 master 来修复一个 bug。如何临时记录当前修改方便下次使用?在当前分支做如下操作:

      git stash      # 保存当前未 commit 的修改
      git co master
      git co -b bugfix_blabla
      ...
      git co working_branch    # 切换回之前没完成的分支
      git stash pop           # 之前的修改又回来了
    

patch apply

当一个分支落后 master 太多更新,导致 git rebase -i 太多冲突。可以使用 apply patch 的方法。原理是通过 format-patch 指令将若干个 commit 导出成一个文本文件,然后把 patch 文件视为一个没有起始节点的 branch 合并到 master 中,这一过程相当于重新操作patch中包含的每一次提交,因此不会丢失 commit history ,并且只需要处理代码上的冲突。

注意:由于不推荐直接在 master 分支直接操作 commit,因此使用 patch 的操作最好在一个基于最新版 master 创建的临时本地分支上进行。

  1. git checkout master
  2. git fetch --all --tags
  3. git merge origin/master
  4. git checkout -b temp_merge
  5. git checkout branch_to_merge
  6. git format-patch master --stdout > commit.patch
  7. git checkout temp_merge
  8. git am commit.patch
  9. rm commit.patch

如果当前 branch 的 history 过于凌乱导致 format-patch 得到的 patch 并不理想,可以将指令中代表分支的 master 换成当前分支下,最后一个不需要写入 patch 的 commit id。

To check in empty directory

Create .gitignore file which contains:

# Ignore everything in this directory 
* 
# Except this file 
!.gitignore
!README

The README file contains doc to explain why this dir is empty

原文参考 https://github.com/shijialee/tech_onboarding_docs/wiki/git-workflow