日常工作中Git常用命令(持续更新)

前言

因为之前工作中一直用的控制版本都是svn,现在改为用git了,不得不说git是非常强大的,自然而然功能多了,命令也就多了,有些常用的命令不是忘记就是和svn搞混淆,索性记录一下常用到的命令,用到什么了就记录一下,方便以后查看

恢复本地删除的文件

直接从本地把文件checkout出来就可以了,用不着从远程服务器上pull下来,因为,所以的历史版本你的本地都有的

处理冲突

如果系统中有一些配置文件在服务器上做了配置修改,然后后续开发又新添加一些配置项的时候,在发布这个配置文件的时候,会发生代码冲突:

1
2
3
error: Your local changes to the following files would be
overwritten by merge:protected/config/main.php.Please,commit your
changes or stash them before you can merge.

如果希望保留生产服务器上所做的改动,仅仅并入新配置项

1
2
3
git stash
git pull
git stash pop

然后可以使用git diff -w +文件名 来确认代码自动合并的情况.

如果希望用代码库中的文件完全覆盖本地工作版本

1
2
git reset --hard
git pull

其中git reset是针对版本,如果想针对文件回退本地修改,使用

1
git checkout HEAD file_to_restore

更新本地代码

最好不要用git pul要使用git fetch

1
2
pull = fetch + merge
fetch = fetch

版本库初始化

本地建立一个Git版本库

1
2
3
$ mkdir helloworld
$ cd helloworld
$ git init

在版本库中添加示例文件,如README.md文件

1
2
$ git add README.md
$ git commit -m "README for this project."

为版本库添加名为origin的远程版本库

1
$ git remote add origin git@github.com:gotgithub/helloworld.git

执行推送命令,完成GitHub版本库的初始化

注意命令行中的-u参数,在推送成功后自动建立本地分支与远程版本库分支的追踪。

1
$ git push -u origin master

合并分支

当我们在分之上改动完毕,问题解决之后,需要将分支的修改合并到主分支上,需要用到合并分支命令。
切换到主分支,执行:

1
git merge branch-name

需要特别说明的是,git merge 后面可以跟一些参数来达到不同的结果,如下图所示:

–no-ff指的是强行关闭fast-forward方式
fast-forward方式就是当条件允许的时候,git直接把HEAD指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建commit
总结来说–no-ff的作用:不使用fast-forward方式合并,保留分支的commit历史

删除分支

删除本地分支

1
git branch -d branchName

强制删除的话换-d换成-D

删除远程分支

1
git push origin :branchName

有种方便记忆这条命令的方法:记住我们不久前见过的 git push [远程名] [本地分支]:[远程分支] 语法,如果省略 [本地分支],那就等于是在说“在这里提取空白然后把它变成[远程分支]”

还有一种方式:

1
git push origin --delete branchName

Tag相关

添加轻量级Tag

轻量级的Tag就是在当前的commit上加一个label,不包括其他信息,不推荐使用

1
git tag v1.0-lw

添加普通Tag

正常的Tag是相当于一个正常的commit,包括谁提交的,提交事件等信息,推荐使用这种形式的Tag

1
git tag -a v1.4 -m "my version 1.4"

push单个Tag

1
git push origin v1.5

push所有Tag

1
git push origin --tags

删除本地Tag

1
git tag -d v1.0

删除远程Tag

1
git push origin :v1.0

忽略已经提交的文件夹(文件)

一般我们在用git提交第一版的时候,难免会提交一些我们没必要提交的文件或者文件夹,比如Android Studio编写的Android项目的.idea文件夹,如果我们已经提交了这个文件夹,想忽略掉该文件夹,以后不提交的话,我们可以这样做:

1
git rm -r --cached .idea/

如果是忽略文件夹,需要-r参数,如果是文件的话,就不需要-r参数了
执行完上面的代码之后,然后我们再修改.gitignore,最后commit就OK了

更新forked仓库

有时候我们fork远程仓库到我们自己的仓库之后,远程仓库更新的话,forked的仓库也需要保持同步,下面是本地fork仓库同步远程仓库的步骤:

1.添加远程仓库,取一个别名:upstream

1
git remote add upstream git@github.com:huhulab/MultiAdType.git

2.获取所有远程分支到远程跟踪分之,比如upstream/master

1
git fetch upstream

3.确认你在你的主分支上

1
git checkout master

4.重写master分支

1
git rebase upstream/master

5.更新你github上forked的仓库

1
git push -f origin master

第一次rebase的时候需要使用-f参数,强制push

回退提交

分两种情况

没有push到服务器上的提交

1
2
3
git reset --hard HEAD~1
or
git reset --hard commit_id

带hard参数是将该commit所有的改动也全部还原回去,也就是说此操作之后,分支是clean状态的,如果想保留更改,只是想回退掉该commit的话,就不要带–hard参数

已经push到服务器上了

这种情况,如果分支允许强制push的话,你可以这样操作:
首先,使用上面那个命令将本地代码回退到你想要回退的commit
然后执行:

1
git push -f

强制用本地的版本覆盖服务器的版本,这样在不产生新提交的情况下,就把服务器分支上已经提交的错误提交回退掉,但是一般不推荐这样做,这样会有风险,而且一般团队里面master分支也是不允许强制push的

这个时候就需要revert命令了
通常情况下,我们回退一个commit,只需要执行:

1
git revert commit

但是,当你回退的是通过merge的提交的时候,直接直行上面命令,你会得到如下错误:

1
2
error: Commit g is a merge but no -m option was given.
fatal: revert failed

这个时候你需要如下操作:

1
git revert -m 1 commit_id

需要说明的是,m代表的是主线,通常是master分支,m后面的参数1或者2代表的是parent在merge commit信息中的顺序