首先, 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的优势是可以创建不同的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