Git使用手册

作者: 李佶澳   转载请保留:原文地址   更新时间:2018/06/21 15:45:09

摘要

Git的操作经常忘记, 这里记录下常用的操作。Git中文手册图解Git常用 Git 命令清单是很好的资料。

可以参考beego的项目管理:

git project

设置代理

有一些项目使用了自己的git服务器,因为“墙”的存在,从国内访问这些git服务的时候,需要通过能够翻墙的代理。

可以设置为全局的:

git config --global http.proxy 127.0.0.1:49710
git config --global https.proxy 127.0.0.1:49710
git config --global http.sslverify false 

git的全局配置文件是~/.gitconfig:

[http]
	proxy = 127.0.0.1:49710
	sslverify = false
[https]
	proxy = 127.0.0.1:49710

不需要代理的时候,可以用#号注释掉。

将repo获取到以后,可以在repo里设置local config,只在当前repo中使用代理:

git config --local http.proxy 127.0.0.1:49710
git config --local https.proxy 127.0.0.1:49710
git config --local http.sslverify false 

远端仓库的地址设置

remote命令用来设置跟踪的远程仓库地址,默认有一个名为origin的远程跟踪,用git remote -v可以看到当前所有的远程跟踪,例如:

$ git remote -v
origin	https://github.com/introclass/kubernetes-yamls.git (fetch)
origin	https://github.com/introclass/kubernetes-yamls.git (push)

remote set-url子命令更改远程跟踪的地址:

git remote set-url origin https://github.com/lijiaocn/kube-lb.git

增加远程跟踪

remote add命令添加一个新的远程跟踪,例如下面添加了一个名为upstream的远程跟踪:

➜  kubernetes-yamls git:(master) ✗ git remote add upstream https://github.com/lijiaocn/kubernetes-yamls.git
➜  kubernetes-yamls git:(master) ✗ git remote -v
origin	https://github.com/introclass/kubernetes-yamls.git (fetch)
origin	https://github.com/introclass/kubernetes-yamls.git (push)
upstream	https://github.com/lijiaocn/kubernetes-yamls.git (fetch)
upstream	https://github.com/lijiaocn/kubernetes-yamls.git (push)zo

添加了新的远程跟踪之后,要正常工作,需要先用fetch命令将新的远程跟踪的代码拉取:

➜  kubernetes-yamls git:(another_repo) ✗  git fetch upstream
From https://github.com/lijiaocn/kubernetes-yamls
 * [new branch]      master     -> upstream/master

创建多个远程跟踪的好处是:可以将一个远程仓库中的更新同步到本地,然后提交到另一个远程仓库中,见github协作开发

另外要注意的是,远程跟踪只存在于本地,不能提交到远程仓库中。

删除远程跟踪

remote remove删除远程跟踪:

git remote remove upstream

为不同分支设置不同的远程跟踪

可以为本地不同的分支设置不同的跟踪地址,下面新建一个名为another_repo的分支:

$ git branch another_repo
$ git checkout another_repo

git branch -vv查看分支的远程跟踪,[]中是分支的远程跟踪:

$ git branch -vv
* another_repo 92ecfec add NodePort                  # another_repo分支当前没有远程跟踪
  master       92ecfec [origin/master] add NodePort

为another_repo设置远程跟踪,跟踪upstream中的master分支:

$ git branch -u upstream/master another_repo
➜  kubernetes-yamls git:(another_repo) ✗  git branch -u upstream/master another_repo
Branch 'another_repo' set up to track remote branch 'master' from 'upstream'.

这时候可以看到another_repo分支有了跟踪的分支:

$ git branch -vv
* another_repo 92ecfec [upstream/master] add NodePort
  master       92ecfec [origin/master] add NodePort

注意即使分支跟踪的是另一个远程仓库中的分支,也可以被推送到远程仓库中:

git push origin another_repo:another_repo

但是如果这时你从远程仓库中取出another_repo的分支,会发现它跟踪的不是upstream中的分支,而是origin中的分支:

$ git branch -vv
* another_repo 92ecfec [origin/another_repo] add NodePort
  master       92ecfec [origin/master] add NodePort

因此最好不要把跟踪另一个远程仓库的分支推送到远程仓库中,除非你确定就是要这样操作。

github协作开发

第一步,在github上fork目标项目。

第二步,将fork到自己账户中项目代码clone到本地。

第三步,在本地添加上游代码的索引,这里命名为upstream:

git remote add upstream  https://github.com/kubernetes/kubernetes

第四步,在本地开始开发工作,本地的开发过程参考下一节“在分支中开发”。

第五步,获取上游代码的更新,注意upstream是上游代码的索引:

git remote update upstream

第六步,将本地分支设置为基于最新的上游代码:

git rebase upstream/master  (将当前所在分支的设置为基于upstream/master)

git rebase upstream/branchX  branchL  (将本地branchL分支的修改设置为基于upstream/branchX) 

第七步,将本地的修改提交到自己的repo中。

第八步,在github上发起pull request。

github中发布版本

创建一个发布分支:

git branch release-v1.8.0

将发布分支推送到远端:

git push origin release-v1.8.0:release-v1.8.0

在项目的github主页上,点击release,进行发布,注意在分支上进行release。

如果要删除release,只需要在本地和远端删除对应的tag即可。Git: 删除tag

在分支中开发

Merging vs Rebasing-zh(Merging vs Rebasing-en)中给出特别详细的说明。

第一步,获取master代码:

git checkout master

第二步,本地创建开发分支:

git checkout -b dev-branch

第三步,本地开发完成后,提交开发分支中的内容:

git add .

git status

git commit --verbose  

注意:切换到其它的分支之前一定要先commit,否则其它分支中的内容会受影响。

可以将多个commit合并为一个commit,见“合并commit”一节。

将本次的commit合并到上一次commit,可以使用“–amend”选项

第四步,如果其他人员也参与这个分支的开发,将本地分支推送到远端:

git push origin local_branch:remote_branch  

第五步,将远端的更新下载到本地:

git fetch origin

第六步,将本地开发分支的内容设置为基于最新的的master代码:

git rebase master dev-branch

这个过程会有多次冲突,必须一个一个地解决!然后继续rebase:

git rebase master --continue

如果开发分支是基于另一个分支的,也可以将其修改为基于master分支:

git rebase -onto master  anotherbranch  currunbranch

第七步,在master中合并已经做过rebase的开发分支,注意是merge!

git merge dev-branch

或者在github页面中发起pull request,请求将开发分支中的内容合并到master。

第八步,在master中完成commit、push、打tag:

git add .

git status

git commit

git push

标记tag:

git tag v0.0.X
git push origin v0.0.X

第九步,删除本地开发分支和远端的开发分支:

git branch -d dev-branch
git push origin :dev-branch 

常用git操作

合并commit

从log中找到一个在要合并的分支之前的commit(ffe)

在rebase中设置要合并的commit

git rebase -i ffe

编辑界面如下(将7143, 2a7c合并到ffe39):

 pick ffe398c d1

 s 2a7ccaa d2+d3

 s 714ef1b d4 amend

越靠前的commit越老, 将一个commit前面的pick修改为s, 表示这个commit将和它前面的commit合并为一个commit

保存、推出编辑后,如果存在合并的commit,会立即弹出问本次合并填写注释的编辑窗口,编写新的注释后推出即可

退出注释编辑窗口后,ffe,2a7,714消失, 被一个新的commit取代。

回退

git reset:

git reset --soft:   只将HEAD移动到指定的commit, 不会改动index文件和工作目录

git reset --mixed 或者 git reset:   index文件回退到指定的commit, 不改动工作目录

git reset --hard:  index文件和工作目录都回退到指定的commit

git rm之后,还没有提交:

git reset HEAD <删除的文件或目录>
git checkout <删除的文件或目录>

删除commit:

git reset --hard <commit_id>
git push origin HEAD --force

查看/拉取远程分支

查看:

git branch -r 

拉取远程分支:

git checkout -b 本地分支名 -t 远程分支名

推送分支

git push origin 本地分支:远程分支

删除远程分支

git push origin :远程分支

推送tag

git push origin TagName   //推送指定tag
git push origin --tags    //推送全部tag

删除tag

git tag -d TagName        //删除本地tag
git push origin :TagName  //删除远程tag

永久删除

https://help.github.com/articles/remove-sensitive-data/

http://zpz.name/2287/

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch path/to/your/file' HEAD
git push origin master --force
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now''

配置编辑器

git config --global core.editor vim

代码对比

展示commit2相对于commit1发生的改动:

 git diff  commit1  commit2

子模块,git项目嵌套

通过子模块,可以在一个git项目中包含另一个git项目。

添加子模块:

git submodule add https://github.com/chaconinc/DbConnector [目标路径] 

之后用git status查看,可以发现多出了一个.gitmodules文件,这个文件中记录了子模块信息。。

克隆包含自模块的项目时,子模块会是一个空的目录,需要用下面的两个命令获取子模块的内容。

git submodule init
git submodule update

或者在clone时使用--recursive参数。

更新子模块,可以进入到子模块中更新:

git fetch
git merge

或者使用命令更新所有子模块,默认更新master分支:

git submodule update --remote

如果要跟踪其它分支,在.gitmodules中配置:

git config -f .gitmodules submodule.DbConnector.branch stable

查看子模块的提交日志:

git log -p --submodule

如果要在子模块中进行修改并提交,在子模块中进行修改后,用下面的命令合并子模块的上游代码:

git submodule update --remote --merge    //merge
git submodule update --remote --rebase   //rebase
git submodule update --remote            //获取子模块更新,不做merge

在推送主项目中的变更时,可以用下面的命令:

git push --recurse-submodules=check      //如果子模块没有推送,push失败
git push --recurse-submodules=on-demand  //自动推送子模块,如果子模块推送失败,push失败

在所有的子模块中执行命令:

git submodule foreach 'git stash'

删除子模块时,将子模块目录删除后,在.gitmodules和.git/config中子模块相关信息删除。

常见问题解决

中文名乱码

解决中文文件名显示乱码:

git config core.quotepath false

参考

  1. undo git rm
  2. Merging vs Rebasing-zh
  3. Merging vs Rebasing-en
  4. Git: 在分支中开发
  5. Git: 删除tag
  6. beego git branch
  7. Git 工具 - 子模块
  8. Git中文手册
  9. 图解Git
  10. 常用 Git 命令清单

本文原创首发于网站:www.lijiaocn.com

QQ交流群

区块链实践互助QQ群:576555864

Kubernetes实践互助QQ群:947371129

Prometheus实践互助QQ群:952461804

Kong/Envoy实践互助QQ群:952503851

Ansible实践互助QQ群:955105412

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作 友情链接: lijiaocn github.com