Git

配置

配置默认编辑器

有些操作可能需要用编辑器填写 commit 内容, 比如合并 commit 时, 默认编辑器可能是 gnome nano, 如果想改成 vim, 可以在~/.bashrc里添加:

export VISUAL=vim
export EDITOR="$VISUAL"

然后source ~/.bashrc, 这样全局都是 vim 编辑器了
注: 前提是你用的 bash, 如果是 zsh, 那就修改~/.zshrc

相关命令

准备工作

  • 创建版本库。在需要版本控制的文件夹下输入此命令,才能进行版本控制

    git init

  • 查看版本状态

    git status


分支

  • 查看分支

    git branch

  • 查看分支, 按 commit 时间排序

    git branch --sort=-committerdate # desc
    git branch --sort=committerdate # asc

  • 创建分支

    git branch branch_name

  • 创建并切换到一个分支

    git checkout -b branch_name

  • 合并分支

    git merge branch_name

  • 删除分支

    git branch -d branch_name

  • 删除远程分支

    git push origin —delete <branch_name>

  • 批量删除分支

    https://stackoverflow.com/questions/3670355/can-you-delete-multiple-branches-in-one-command-with-git

    删除 3.2 3.2.1 3.2.2 三个分支

    $ git branch -D 3.2 3.2.1 3.2.2
    

    更 geek 的方法是

    $ git branch -D `git branch | grep -E '^3\.2\..*'`
    
  • 如何用远程另外的分支覆盖本地分支

    本地分支名为 yangle,用远程 master 分支覆盖此分支,保证 yangle 分支和远程 master 分支一样。在本地 yangle 分支下:

    $ git fetch origin
    $ git reset --hard origin/master
    # origin/master实际上是指fetch下来已经在本地的分支
    
  • 重命名本地分支

    git branch -m new_branch_name


查看

  • 查看修改记录日志

    git log

  • 查看修改日志一条一行显示

    git log --pretty=oneline

  • 日志导出

    以导出当前分支最近 50 条 log 为例

    git log -50 > log50_latest_commits.txt

  • 查看文件修改信息

    git diff [文件名]


回退

  • 版本回退到上一步

    git reset --hard HEAD^

  • 版本回退到前 5 步

    git reset --hard HEAD~5

  • 根据 commit id 来回退

    git reset --hard *******(id)

  • 撤销上一个 commit, 保留修改

    git reset --soft HEAD^


编辑

  • 如何从另外一个分支复制文件到当前分支

    git checkout branch_name file_path

  • 如何将另外一个分支的文件夹全部复制到当前分支

    git checkout <other-branch> -- <path-name>

  • 如何暂时保存当前修改
    当我们正在编辑文件时, 可能中途需要切换分支, 或者当前分支需要 push. 需要暂时保留这些修改, 但是不需要提交. 那么可以:
    git stash或者git stash save "your message"
    然后可以用git stash list查看这些信息
    然后用git stash pop回到最近的 stash


tag

  • create tag
    git tag tagname

  • delete local tag
    git tag -d tagname

  • push tag
    git push --tag

  • delete origin tag
    git push origin :refs/tags/tagname

  • checkout tag
    git checkout <tagname>

submodule

在某个仓库里有 submodule, 如果想要这个仓库运行起来, 需要执行:

$ git submodule update --init

答疑

如何让 GIT 不跟踪某些文件或文件夹

.gitignore文件, 将不需跟踪的文件和文件夹放入到这个文件里
规则参照https://www.atlassian.com/git/tutorials/saving-changes/gitignore

如果文件以及提交到了仓库, 那么还需要将文件从暂存区里移出, 采用:
git rm --cached readme.txt
参照https://blog.csdn.net/leedaning/article/details/44976319

如果是移除某个路径
参照http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/:

$ git rm -r --cached <directory>

how to set ingore all files except specify files

# Ignore all files
*

# But keep these specific files
!update_map.sh

远程仓库

  1. 删除

    $ git remote -v
    # View current remotes
    origin  https://github.com/OWNER/REPOSITORY.git (fetch)
    origin  https://github.com/OWNER/REPOSITORY.git (push)
    destination  https://github.com/FORKER/REPOSITORY.git (fetch)
    destination  https://github.com/FORKER/REPOSITORY.git (push)
    
    $ git remote rm destination
    # Remove remote
    $ git remote -v
    # Verify it's gone
    origin  https://github.com/OWNER/REPOSITORY.git (fetch)
    origin  https://github.com/OWNER/REPOSITORY.git (push)
    
  2. 添加

    $ git remote add origin <remote_repo_url>
    
  3. 修改远程仓库链接

    $ git remote set-url origin ***
    

修改 commit message

# 修改最近一条commit信息
$ git commit --amend

合并 commit

如果要将最近的两个 commit 合并为一个, 可以这样:

$ git reset --soft "HEAD^"
# 或者
$ git reset --soft "HEAD~1"
# 如果是最近的三个commit
$ git reset --soft "HEAD~2"
# 然后
$ git commit --amend

git rebase 的用法

5.1 代码合并:Merge、Rebase 的选择

git push 失败

ssh: connect to host github.com port 22: Connection timed out

解决方法:
配置~/.ssh/config文件, 添加如下内容:

Host github.com
  Hostname ssh.github.com
  Port 443

工作流

工作流参考资料

采用 git-flow,原理参照:

http://www.ruanyifeng.com/blog/2012/07/git.html

https://www.git-tower.com/learn/git/ebook/cn/command-line/advanced-topics/git-flow

http://nvie.com/posts/a-successful-git-branching-model/

https://github.com/tiimgreen/github-cheat-sheet

https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

分支管理

共分为 5 个分支,2 个稳定分支,3 个临时分支

  • 稳定分支

    master 和 develop 分支会作为保护分支,必需通过 code review 才能合并

    分支 源分支 功能
    master master 稳定分支,生产上线
    develop master 所有开发的分支都从这个分支创建
  • 临时分支

    分支 源分支 功能
    feature/* develop 新功能开发
    release/* develop develop 上创建的分支,用于发布前测试
    hotfix/* master 生产环境有 bug,临时紧急修复的分支

流程

  1. 开发
    分支:feature-*
    操作人员:开发
    步骤:

    • 开发一个新功能时,从 develop 分支上切一个分支,命令规范为 feature/*
      # 新建分支
      $ git checkout -b feature/new-feature develop
      # 更新分支保证是最新代码
      $ git rebase origin/develop
      
    • 联调和开发测试均在此分支上
      发布到测试服务器上供前端联调时, docker build 打 dev 的 tag
      发布后, 后端的地址是: clm-fe.dev.didatrip.com
    • 在本地构建镜像
      $ docker build . -t registry.cn-beijing.aliyuncs.com/rock2018/clm:dev
      $ docker push registry.cn-beijing.aliyuncs.com/rock2018/clm
      
    • 在测试服务器上上线
      $ docker pull registry.cn-beijing.aliyuncs.com/rock2018/clm:dev && docker-compose -f /var/www/devops/docker-compose-test.yml up -d
      
    • 测试通过,提交 merge request,通过 code review 之后合并到 develop 上
      如果此功能不在这个发版周期内, 先不要合并到 master
  2. 总体测试

    分支:release/*
    操作人员:分支管理人员
    一个周期内(比如一周),有多个 feature 开发,开发完成之后都合并到 develop 分支上,然后从 develop 分支上 checkout 一个 test 分支,命名规范为 release/日期,例如:test-20171216
    如后续有 feature 分支合并到 develop 上随这个版本周期发版, 那么 rebase develop, 继续在 release 分支上测试 测试人员在此分支上做整体测试,若测试有问题,开发人员在 release 分支上修改,直到测试通过
    提交测试之前后端开发人员需在测试环境自测一遍
    测试前需要给测试人员发送邮件,抄送qa@luojilab.com,说明测试要点

  3. 发布

    分支:master
    master 和 develop 分支分别合并 release 分支,生产发布 master 分支

  4. 命令

    • git flow init

      git flow init

    • Creating a feature branch

      git flow feature start feature_branch

    • Finishing a feature branch

      git flow feature finish feature_branch

参考资料

https://github.com/geeeeeeeeek/git-recipes/wiki

http://www.ruanyifeng.com/blog/2015/08/git-use-process.html

http://www.ruanyifeng.com/blog/2012/07/git.html

https://www.git-tower.com/learn/git/ebook/cn/command-line/advanced-topics/git-flow

https://www.ibm.com/developerworks/cn/java/j-lo-git-mange/index.html