git进阶命令

首先, clone 一个远端仓库,到其目录下:

Git clone git://example.com/myproject $ cd myproject

然后,看看你本地有什么分支:

$ git branch * master

但是有些其他分支你在的仓库里面是隐藏的,你可以加上-a选项来查看它们:

$ git branch -a
* master
  origin/HEAD
  origin/master
  origin/v1.0-stable
  origin/experimental

如果你现快速的代上面的分支,你可以直接切换到那个分支:

$ git checkout origin/experimental

但是,如果你想在那个分支工作的话,你就需要创建一个本地分支:

$ git checkout -b experimental origin/experimental

现在,如果你看看你的本地分支,你会看到:

$ git branch
  master
* experimental

你还可以用git remote命令跟踪多个远程分支

$ git remote add win32 git://gutup.com/users/joe/myproject-linux-port
$ git branch -a
* master
  origin/HEAD
  origin/master
  origin/v1.0-stable
  origin/experimental
  linux/master
  linux/new-widgets

你可以用gitk查看你做了些什么:

$ gitk --all &

1.是谁弄乱了我的代码

git blame [file_name]

2. 暂存文件的部分改动

git add -p [file_name]

3. 压缩多个Commit

git rebase -i HEAD~[number]//压缩最近的number个commit

注:2和3的详细用法参考http://www.oschina.net/translate/10-tips-git-next-level

4. Stash未提交的更改

git stash//暂存当前的改动
git stash save “修改说明信息" //暂存当前的改动
git stash list //暂存的改动列表
git stash apply //恢复暂存的所有改动
git stash apply stash@{num}//恢复暂存的某个改动,num为通过git stash list查出的编号
git stash pop //将git stash栈中最后一个版本取出来恢复

5.IDE提供的shelve(搁置)的功能

有一些IDE工具(IDEA/PhpStorm/AndroidStudio)提供了shelve的功能,即把还没写完的代码先搁在一边。使用方法:

首先在IDE的底部找到“Changes”,点开会有local的选项卡,选中你要搁置的代码,点击右键,选择“Shelve Changes”,在提交的输入框中输入你的注释,以便回来的时候识别你需要的版本,点击“Shelve Changes”键即可。这时选项卡上会多一个“Shelf”的选项卡,里面就有你搁置的代码。

这时候你可以去old分支修改代码,改完了之后回到new分支,到“Shelf”选项卡下选择你要恢复的代码或者版本,点击右键选择“Unshelve Changes”,你的搁置的代码就回来了。

6. 拣出某次更改(把已经提交的commit, 从一个分支放到另一个分支

git cherry-pick    详见http://blog.csdn.net/hudashi/article/details/7669462

7.git fetch, git pull, git pull -rebase区别

http://blog.csdn.net/duomengwuyou/article/details/51199597

8.git 删除本地分支

git branch -D br_name

9.git 删除远程分支

git push origin :br_name  (origin 后面有空格)

10.本地代码库回滚

git reset --hard commit-id :回滚到commit-id,将commit-id之后提交的commit都去除    --soft

git reset --hard HEAD~3:将最近3次的提交回滚  --soft

如果只回退一个最新commit:git reset HEAD^(不加时默认是--mixed)

 

git checkout . #本地所有修改的。没有的提交的,都返回到原来的状态

git clean -df #返回到某个节点

git clean 参数

  -n 显示 将要 删除的 文件 和 目录

  -f 删除 文件

  -df 删除 文件 和 目录

因此,可以使用  “git checkout . && git clean -xdf”  删除本地的所有修改

11.远程代码库回滚

这个是重点要说的内容,过程比本地回滚要复杂
应用场景:自动部署系统发布后发现问题,需要回滚到某一个commit,再重新发布
原理:先将本地分支退回到某个commit,删除远程分支,再重新push本地分支
操作步骤:
1、git checkout the_branch
2、git pull
3、git branch the_branch_backup //备份一下这个分支当前的情况
4、git reset --hard the_commit_id //把the_branch本地回滚到the_commit_id
5、git push origin :the_branch //删除远程 the_branch
6、git push origin the_branch //用回滚后的本地分支重新建立远程分支
7、git push origin :the_branch_backup //如果前面都成功了,删除这个备份分支
如果使用了gerrit做远程代码中心库和code review平台,需要确保操作git的用户具备分支的push权限,并且选择了 Force Push选项(在push权限设置里有这个选项)
另外,gerrit中心库是个bare库,将HEAD默认指向了master,因此master分支是不能进行删除操作的,最好不要选择删除master分支的策略,换用其他分支。如果一定要这样做,可以考虑到gerrit服务器上修改HEAD指针。。。不建议这样搞

12.代码回滚详细介绍

这是开发中很常见的问题,所以git的取消提交,回退甚至返回上一版本都是特别重要的.
大致分为下面2种情况:

1.没有push
这种情况发生在你的本地代码仓库,可能你add ,commit 以后发现代码有点问题,准备取消提交,用到下面命令
reset
git reset [--soft | --mixed | --hard

上面常见三种类型

--mixed
会保留源码,只是将git commit和index 信息回退到了某个版本.
git reset 默认是 --mixed 模式
git reset --mixed 等价于 git reset

--soft
保留源码,只回退到commit 信息到某个版本.不涉及index的回退,如果还需要提交,直接commit即可.

--hard
源码也会回退到某个版本,commit和index 都回回退到某个版本.(注意,这种方式是改变本地代码仓库源码)
当然有人在push代码以后,也使用 reset --hard <commit...> 回退代码到某个版本之前,但是这样会有一个问题,你线上的代码没有变,线上commit,index都没有变,当你把本地代码修改完提交的时候你会发现权是冲突.....
所以,这种情况你要使用下面的方式

2.已经push
对于已经把代码push到线上仓库,你回退本地代码其实也想同时回退线上代码,回滚到某个指定的版本,线上,线下代码保持一致.你要用到下面的命令

revert
git revert用于反转提交,执行evert命令时要求工作树必须是干净的.
git revert用一个新提交来消除一个历史提交所做的任何修改.
revert 之后你的本地代码会回滚到指定的历史版本,这时你再 git push 既可以把线上的代码更新.(这里不会像reset造成冲突的问题)

revert 使用,需要先找到你想回滚版本唯一的commit标识代码,可以用 git log 或者在adgit搭建的web环境历史提交记录里查看.
git revert c011eb3c20ba6fb38cc94fe5a8dda366a3990c61

通常,前几位即可
git revert c011eb3

git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit
看似达到的效果是一样的,其实完全不同.
第一:
上面我们说的如果你已经push到线上代码库, reset 删除指定commit以后,你git push可能导致一大堆冲突.但是revert 并不会.
第二:
如果在日后现有分支和历史分支需要合并的时候,reset 恢复部分的代码依然会出现在历史分支里.但是revert 方向提交的commit 并不会出现在历史分支里.
第三:
reset 是在正常的commit历史中,删除了指定的commit,这时 HEAD 是向后移动了,而 revert 是在正常的commit历史中再commit一次,只不过是反向提交,他的 HEAD 是一直向前的.
更详细参见:http://blog.csdn.net/hudashi/article/details/7664464/

13.git diff

(1)比较上次提交commit和上上次提交
    git diff HEAD^ HEAD
(2)比较两个历史版本之间的差异
    git diff SHA1 SHA2
更多参看:http://www.cnblogs.com/wish123/p/3963224.html

14.gitignore

(1).gitignore文件是针对未添加到版本控制的文件,将这些文件标明在.gitignore文件中,可不再提示“这些文件未添加版本控制”。对于开始已经被加入到版本控制的文件,直接在.gitignore文件中设置是无效的。需要先做一下处理(文件名支持正则表达式,如 *.iml,所有iml后缀文件):

git rm --cached -r [dirname]
git rm --cached [filename]
而后再把这些文件[夹]配置到.gitignore文件中
git commit -m 'comment'
git push
之后便会生效

(2).gitignore文件配置举例(.gitignore文件放在git项目根目录下(与.git文件夹同一个目录))
[filename] #忽略该文件
[dirname]/* #忽略该文件夹及下面所有文件
*.[suffixName] #忽略当前文件夹(不含子文件夹)下该后缀的所有文件
[dirname]/*.[suffixName] #忽略当前文件夹(不含子文件夹)下该后缀的所有文件
(3)有些windows系统版本不允许新建只有后缀没有文件名的文件,可以采用 另存为 或 重命名的方式(ren gitignore.txt .gitignore)创建.gitignore文件

15.git 获取最近一次提交的commit id

获取完整commit id(如:14123c8877e6ebdc220e205d92fc70feaf06dab1)

git rev-parse HEAD

获取short commit id(如:14123c8)

git rev-parse --short HEAD
16.命令查看某次修改
(1)git log 显示历史的提交列表
(2)git log -p -n 最近的n次提交的所有详细改动
(3)git show <commit-hashId> 显示某次提交的修改内容
(4)git show <commit-hashId> filename 显示某次提交的某个内容的修改信息
17.强制放弃修改

本地修改了一些文件,其中包含修改、新增、删除的,不需要了想要丢弃,于是做了git check -- .操作,但是只放弃了修改的文件,新增和删除的仍然没有恢复,于是百度了下,使用如下命令:

git checkout . && git clean -df

可以放弃所有修改、新增、删除文件

git checkout . //放弃本地修改,没有提交的可以回到未修改前版本

git clean -f 是从工作目录中移除没有track的文件.
通常的参数是git clean -df:
-d表示同时移除目录,-f表示force,因为在git的配置文件中, clean.requireForce=true,如果不加-f,clean将会拒绝执行.
 
18.Git merge 不同的branch

Git的优势是可以创建不同的branch,然后在每个branch上开发。那么问题是:如果不同的branch之间需要做同步,比如sourceBranch上做的修改也需要同步到targetBranch,改怎么做?

1. 如果一个branch是有远程Git server管理的,另一个branch是自己本地的

    cd <your workspace>

    git branch  //假定现在所在的branch是targetBranch,并最好保证没有未提交的修改,并且已经更新到最新

    git checkout -b sourceBranch  //创建一个本地的sourceBranch并切换到sourceBranch

    git commit  //把sourceBranch上做的修改先提交

    git checkout targetBranch  //切换回targetBranch

    git merge --no-ff sourceBranch  //把sourceBranch的修改merge到targetBranch。注意:建议merge的时候总是用 --no-ff 选项

    git status  //保证现在workspace是干净的

    git push   //push到远程,如果远程有新的修改,先做一下git pull

2. 如果两个branch都是远程管理的,想把branchB的内容同步到branchA上

   cd <your workspace>

   git branch  //假定现在所在的branch是branchA,并最好保证没有未提交的修改,并且已经更新到最新

   git checkout sourceBranch  //确保同一个workspace能在不同的branch直接切换,即保证 .git/config里 [remote "origin"] 的内容是 fetch = +refs/heads/*:refs/remotes/origin/*

   git merge targetBranch

   解决conflicts如果merge的结果里有显示conflicts

   git commit  //解决冲突后先commit到sourceBranch

   git checkout targetBranch  //切换到targetBranch

   git merge --no-ff sourceBranch  //建议merge的时候总是用 --no-ff 选项

   git push origin targetBranch   //把sourceBranch的修改merge到targetBranch之后,push到远程的targetBranch

其中关于--no-ff 参考 https://segmentfault.com/q/1010000002477106

posted @ 2017-05-17 17:07  庚拓天下  阅读(1393)  评论(0编辑  收藏  举报