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 [文件名]


Revert

  • 版本回退到上一步

    git reset --hard HEAD^

  • 版本回退到前 5 步

    git reset --hard HEAD~5

  • 根据 commit id 来回退

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

  • Undo commit and keep changes git reset --soft HEAD^

  • Undo add and keep changes git reset


编辑

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

    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 pull need username and password

if your repo was cloned by https, you need to pull with username and password next time. How to avoid input username and password every time?

  1. create a file ~/.git-credentials and add your username and password

    https://username:password@github.com
    
  2. set git config

     git config --global credential.helper store
    

    Then you can pull without username and password next time.

工作流

工作流参考资料

采用 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