操作命令记录

2017-04-22  本文已影响0人  老沈Rosen

cherry-pick

cherry-pick,就是下面ruby_client不想要整个分支,只想要e43a6,那就樱桃挑选e43a6就可以。

Paste_Image.png
Paste_Image.png

关于Branch

  1. Creating a New Branch,
    只是创建啦testing branch,并不切换到testing
$ git branch testing
  1. 查看branch历史
    会显示所有它的commit,还会显示哪个branch指向哪个commit,还有HEAD当前指向哪个branch。
$ git log --oneline --decorate

这个命令显示branch历史是图形样式的。

$ git log --oneline --decorate --graph --all
  1. 切换branch
    working tree里面文件都变成testing所指向那个commit指向的那个snapshot的样子。
    HEAD文件也从原来的branch变成指向testing branch
$ git checkout testing
  1. 新建并切换branch
    该命令新建一个iss53 branch,并且切换到该branch
$ git checkout -b iss53
//上面一句相当于下面两句命令。
$ git branch iss53
$ git checkout iss53
  1. 删除分支
    删除名为hotfix的分支。
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
  1. 列出所有的branch
    带有*的是现在checkout的branch
$ git branch
  iss53
 * master
  testing

显示各个branch最后一次commit信息

git branch -v
  iss53     93b412c fix javascript issue
 * master  7a98805 Merge branch 'iss53'
  testing   782fd34 add scott to the author list in the readmes

--merged--no-merged两个参数可以过滤branch

//显示已经merge到当前分支(master)的branch,过滤其他的
$ git branch --merged 
  iss53
 * master
//显示没有merge到当前分支的branch
$ git branch --no-merged 
  testing
//因为testing branch没有merge到当前分支,所以不能直接删除
$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.

关于remote branch

  1. 查看remote branch的信息
git ls-remote [remote]
git remote show [remote]
  1. 克隆远程仓库
git clone //默认存储到origin/master,就是远程服务默认名为origin
git clone -o booyah  //该命令,使得仓库存储到booyah/master
  1. 从远程仓库获取更新
    • 从服务器获取本地没有的分支。
      如果服务器有个新的分支叫serverfix,本地没有
      git fetch origin会获取更新,但我们不会有一个新的本地的serverfix分支,只有一个origin/serverfix远程分支,而且还是不能修改的。
git fetch origin

origin/serverfix远程分支合并当前所在的本地分支上

git merge origin/serverfix

也可以新建一个本地分支(serverfix),checkout这个origin/serverfix远程分支

$ git checkout -b serverfix origin/serverfix
Branch serverfix set up to track remote branch serverfix from origin.
Switched to a new branch 'serverfix'

下面三个命令做的是同样的事情。

// 正常命令,从origin/serverfix获取并创建本地的serverfix分支。
$ git checkout -b serverfix origin/serverfix
// 上面操作太常用,所以git提供啦更简单的命令
$ git checkout --track origin/serverfix
/* 
下面这个命令,更加简单,当本地不存在“serverfix”分支,
且远程服务中,有且只有一个与“serverfix”名字匹配的分支“
git就会自动创建本地分支。
*/
$ git checkout serverfix
  - 设置本地分支的上游分支(就是本地对应远程分支)
//-u 参数代表(upstrem branch)的缩写
$ git branch -u origin/serverfix
  - 从服务器获取remote branch的更新,并合并到当前分支

假设,当前在master分支上,且master分支的(upstream branch)是 origin/master

$ git fetch origin
$ git fetch --all  //这个命令代替上一个,就会把所有远程分支都更新。
//--------------------------------------------------
$ git merge origin/master
//下面两句命令用@{u}和@{upstream}代替origin/master,比较方便
$ git merge @{u}
$ git merge @{upstream}
  - git pull
$ git pull 
//git pull == git fetch + git merge 一个命令其实就是两个的结合
$ git fetch 
$ git merge
  - 删除远程服务器无用的branch
$ git push origin --delete serverfix
To https://github.com/schacon/simplegit
 -[deleted]         serverfix
  1. 添加新的远程服务
git remote add teamone https://sss.github.com/sss/ss
  1. 推送更新到远程服务
    • 将远程没有的本地分支,推送到远程服务器与别人共享
$ git push <remote> <branch>
$ git push origin serverfix

这里git会自动把serverfix扩展成
refs/heads/serverfix:refs/heads/serverfix,就是说把我本地的serverfix更新到远程的serverfix分支中。

git push origin serverfix:serverfix  //这种写法也可以
git push origin serverfix:awesomebranch 
//推送到远程分支时,分支名叫awesomebranch
  1. 查看本地branch与远程branch的关系
    输出结果解释:
    • iss53分支:追踪origin/iss53,ahead 2表示本地有两个commit未推送到远程
    • master分支:追踪origin/master,是与远程分支一致的最新版本
    • serverfix分支:追踪teamone/server-fix-good,远程分支有一个commit为下载并merge到本地,本地有三个commit未推送到远程。
    • testing分支:是完全本地的分支,不追踪任何远程分支。
$ git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
*serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  testing   5ea463a trying something new

关于staging area

  1. 添加文件到staging area
$ git add README test.rb LICENSE
  1. 查看staging area的状态
git status

关于commit

  1. 提交,直接输入信息
$ git commit -m 'The initial commit of my project'
  1. 提交,打开编辑器输入信息
$ git commit 
  1. -a 选项,告诉git提交前,自动将修改回删除的文件添加到staging area。
    但是新增加的,git还没有track的文件不会添加进去。
$ git commit -a -m 'made a change'

关于git diff

  1. 检查有没有whitespace issues(不知道这是什么,先记下来吧)
    在commit之前执行该命令。
git diff --check

关于merge

  1. 将一个branch合并到另一个
    假设目前在hotfix上修复问题,问题修复完成要合并到主分支
    先切换到主分支master,然后git merge hotfix
$ git checkout master
$ git merge hotfix
  1. merge的两种状况
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)

这种合并,会基于图四所示的三个Commit(C2、C4、C5),两个是分支所指向的commit,一个是那两个commit的共同祖先。
最终生成一个新的commit obejct,如图五所示的C6。(Fast-forward类型的merge不产生新的commit)
C6叫做Merge commit,它有两个parent(C4和C5),这就是Merge commit特殊的地方。
合并完毕后,如果iss53没用啦,可以删除掉。


图三
图四
图五

Merge冲突的处理过程

下面merge命令执行后,显示有冲突

$ git merge iss53 

冲突后,Git就暂停啦merge commit的创建,可以用下面命令看是哪些文件冲突。

$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")

有冲突的文件在Unmerged paths条目下列出。
结果中提示啦,用git add命令来标记冲突文件问题已经解决。
下面是冲突文件中的冲突内容的样子,上下两个分支名(HEAD、iss53),(=======)上面属于HEAD,(=======)下面属于iss53。

<<<<<<< HEAD:index.html
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

如果想用可视化工具来解决冲突,用下面的命令就行。
运行命令后输出的文字中,提示啦可以使用的mergetools,在命令行中输入想要用的工具,比如说输入:kdiff3,git就会打开那个工具来进行冲突修改。
如果有多个冲突文件,如下面Merging列出啦:LICENSE和README,会依次打开两个冲突进行修改。

$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare emerge vimdiff
Merging:
LICENSE
README

当然也可以直接用vim来修改冲突文件。

vim README 

冲突修改完毕后,使用git mergetool命令,会自动将冲突文件add到staging area,而vim README命令需要手动用git add来将文件添加。
最后,提交就好啦。

git commit

关于rebase

  1. 最简单的rebase
    仓库的状态如图一所示:
    1.下载master分支时,只有C2,基于C2新建分支(experiment)分支,进行修改
    2.然后别人对仓库进行啦push,master更新到C3
    4.我们可以使用rebase操作将experiment的修改应用到C3


    图一:初始的仓库状态
$ git checkout experiment
$ git rebase master

两行命令作啦啥?
1.对比experiment分支所有commit相对于两个分支的共同祖先(C2)的内容区别,将这些区别存储到临时文件中。
2.把当前分支(experiment)重新设定到rebase指定的分支(master)的commit(也就是C3)上,然后将临时文件中存储的内容区别应用到C3上,产生C4'
3.最后experiment分支设定到C4'上。
4.其实rebase相对于merge的好处是,减少历史信息,如图二,在rebase操作后, 就变成啦一条线,C4就消失啦(不过其实C4的对象仍然有存着的,过一段时间运行GC才会删除)

图二:rebase结果
$ git checkout master
$ git merge experiment

最后就是合并啦,这次Merge属于Fast-forward,Master直接往前移动一下就好啦。


图三:合并
  1. 更有趣一点的rebase


    图四:
$ git rebase --onto master server client

将C8和C9的修改直接应用到master分支上。
结果如图五所示,注意C3的内容不会被应用到master上,只有C8和C9的修改会。


图五:跨越分支rebase
$ git checkout master
$ git merge client

将client合并进master分支,fast-foward


图六:rebase后merge
git rebase [basebranch] [topicbranch]
$ git rebase master server

server分支在master上rebase


$ git checkout master
$ git merge server
$ git branch -d client
$ git branch -d server
把server合并到master后
  1. rebase会引发的问题与解决办法
    我们进行啦开发,产生C2 和 C3
    初始状态:服务器有master分支,指向C1,本地clone后基于C1进行开发
    我们进行啦Fetch,得到C4、C5、C6,进行merge得到C7
    然后别人push到服务器带有merge历史的操作,我们fetch下来进行merge
    别人强制覆盖啦服务器的merge,改为rebase,产生C4',然后我们fetch下来
    提交merge的那人在自己电脑上重新rebase,覆盖掉啦merge,同时强制推送到服务器,我们又fetch啦
    我们用啦git pull,把C7与C4'合并得到C8,但是C4和C4'修改的内容是重复的
    我们git pull合并啦C4'和C7
    解决办法是
git pull --rebase  //代替 git pull
//或者用
git fetch
git rebase teamone/master

得到结果,所以说某些情况下发生这种事情,确保团队别的成员都用git pull --rebase,并且使用rebase的原则是never rebase anything you’ve pushed somewhere.


使用git pull --rebase得到正确结果
上一篇下一篇

猜你喜欢

热点阅读