Subversion svn

概念

Revision相关概念

处于svn管理之下的每个目录下都有个.svn子目录,这个目录称为管理子目录(Administrative
Subdirectory)。目录中的每个文件都会在管理子目录中有一份拷贝,这份拷贝是更新work
copy时该文件在仓库中的最新版本。这个拷贝的版本称为pristine
copy或text-base version,svn术语中也称为BASE revision。

| Keyword | Meaning |
|-----------|--------------------------------------|
| HEAD | 仓库中的最新版本 |
| BASE | 在本地更新操作时对应的版本 |
| COMMITTED | BASE之前(包括BASE)的最后修改的版本 |
| PREV | COMMITTED - 1 |

本地更新到HEAD版本,此时BASE和HEAD是同一个版本。过了一会儿,有其他人做了提交,此时HEAD就与BASE不同了。由此,每个团队成员的BASE有可能是不同的,然而HEAD始终只有一个。BASE,COMMITTED,PREV三个术语都只针对本地某个文件而言。

svn update状态字符含义

| Character | Meaning |
|-----------|--------------------------------------------|
| U | Updated(received changes from the server.) |
| A | Added |
| D | Deleted |
| R | Replaced |
| G | merGed(changes did not inersect) |
| C | Conflict(changes overlapped) |

svn revert

svn revert ITEM 相当于:

  1. 删除ITEM
  2. svn update -r BASE ITEM

它无需去访问repository。

冲突

冲突发生后,subversion会做的三件事情

  1. svn update会打印字符“C”
  2. 往发生冲突的地方添加conflict markers,用以标记冲突的位置。如:

`` example

<<<<<<< .mine

int open_camera(struct frame* pframe, float f)
=======
int open_camera(struct frame* pframe, int k)
>>>>>>> .r10


  1. 针对每个冲突的文件,subversion都会在working

copy中生成以下三个额外的文件

| filename | Meaning |
|------------------|------------------------------------------|
| filename.mine | before update, without conflict markers. |
| filename.rOLDREV | BASE revision before update. |
| filename.rNEWREV | HEAD revision of repository. |

<h3 id="解决冲突的三种办法">解决冲突的三种办法</h3>

  1. 手动合并冲突的文本
  2. 将某个临时文件覆盖掉冲突的文件
  3. 用svn revert filename丢弃本地更改

第1,2种办法,最后都需要运行svn resolved
filename来告诉subversion冲突已经解决,随后三个临时生成的文件即会删除,subversion不再认为还有冲突。第3种办法不需要运行svn
resolved。

<h2 id="树冲突(tree conflicts)参看:Dealing" target="_blank">http://svnbook.red-bean.com/nightly/en/svn.tour.treeconflicts.html">Dealing with Structural Conflicts">树冲突(tree conflicts)参看:Dealing" target="_blank">http://svnbook.red-bean.com/nightly/en/svn.tour.treeconflicts.html">Dealing with Structural Conflicts</h2>

树冲突出现的条件:本地检出文件后,仓库中该文件被删除,本地修改文件,本地运行svn
up。
svn的move操作在实现时会先copy再delete,然而这两者并不会自动关联起来,如果要删除某个本地文件,svn一般会给出警告,然而该delete是与copy关联的delete还是独立的delete,需要用户自己来确定。
还可参看:SVN树冲突和目录丢失问题" target="_blank">http://www.oschina.net/question/103087_12309">SVN树冲突和目录丢失问题

<h3 id="解决方法一:接受仓库的修改">解决方法一:接受仓库的修改</h3>

删除本地文件,再标记为resolved。如果想保留自己的修改,可以能过diff命令保存patch,再手动更改patch中相关文件名为更名后的文件名。更新到新的版本,再应用自己的更新。

<h3 id="解决方法二:使用本地的版本">解决方法二:使用本地的版本</h3>

example

$ svn delete --force code/baz.c 删除服务器上被人更改的文件
$ svn resolve --accept=working code/bar.c 用本地文件作为准。


<h2 id="删除中文帮助信息">删除中文帮助信息</h2>

svn update如果碰到冲突,默认情况下会等待用户输入,此时用lsof -p
xxxx查看svn
update打开的文件,可以查到打开了/usr/share/locale-langpack/zh<sub>CN</sub>/LC<sub>MESSAGES</sub>/subversion.mo。进一步查找发现Ubuntu中是由language-pack-zh-hans包提供的。删除此文件,svn所有命令帮助即变成英文。

<h2 id="保存帐号及密码">保存帐号及密码</h2>

  • 简单认证的帐号信息在~/.subversion/auth/svn.simple下,删除相关文件即可。
  • eclipse中使用JavaHL,方法与上面相同。
  • eclipse中使用SVNKit,帐号信息用eclipse自身的服务中,保存帐号信息的文件的位置为eclipse*configuration/org.eclipse.core.runtime*.keyring。

<h2 id="配置注意事项">配置注意事项</h2>

在svnserve.conf的annon-read=read的情况下,如果在authz中有如下配置 \[/ \]
user=rw 在切换分支或与服务器上的版本进行对比时会出错"svn: Not authorized
to open root of edit
operation"。解决方案有两个,一是设置annon-read=none。二是在authz中添加\*=rw。

<h2 id="删除svn版本控制信息">删除svn版本控制信息</h2>

example

find . -type d -name '.svn' | xargs -n1 rm -fr


如果使用下面的命令删除.svn目录,会有很多警告信息:

example

find . -type d -name '.svn' -exec rm -fr {} \;


正确的写法是:

example

find . -depth -type d -name '.svn' -exec rm -fr {} \;


-depth表示深度优先,会先处理.svn目录下的内容,再删除目录,而不指定-depth,则在删除.svn目录后,再去处理.svn目录下的文件,就会导致大量错误警告信息。

<h2 id="取出单个文件">取出单个文件</h2>

example

svn co --depth=empty svn://host/images images_work_dir
svn up logo.jpg


<h2 id="Tools">Tools</h2>

  1. User" target="_blank">http://www.usvn.info/">User Friendly SVN Subversion仓库管理软件
  2. websvn <http://websvn.tigris.org/>
  3. subversion-tools <http://subversion.tigris.org/> miscellaneous tools

for use with Subversion clients and servers.

<h2 id="eclipse中无法显示Share Project的问题">eclipse中无法显示Share Project的问题</h2>

subclipse中如果没有正常disconnect,同时卸载了Subversion Team
Provider,那么就会无法显示"Share
Project"菜单项。唯一的解决办法是删除该工程(在硬盘上保留),然后再导入该工程。

<h1 id="Git <span class="tag" tag-name="git"><span class="smallcaps">git</span></span>">Git <span class="tag" tag-name="git"><span class="smallcaps">git</span></span></h1>

<h2 id="特点">特点</h2>

  1. CVS,Subversion,Perforce等都是针对每个文件保存更改变量,而git对每个文件保存一个快照,如果某个文件在新版本中没有更改,则会用一个链接指向未更改的文件。
  2. Git中大量的操作都是本地操作,所有的历史都保存在本地数据为中,这与其他几种VDS有很大不同。
  3. Git中的每个文件都会生成hash码(check-sum),用的算法是SHA-1。
  4. Git只添加数据,而不能删除数据。

<h2 id="配置">配置</h2>

<h3 id="https用户名和密码">https用户名和密码</h3>

  1. 使用.git-credentials
example https://{username}:{password}@github.com

  1. 使用credential.helper
example

git config --global credential.helper store


  1. 使用.netrc
example

machine {git account name}.github.com
login your-usernmae
password your-password


<h3 id="Multiple SSH Keys settings for different github account">Multiple SSH Keys settings for different github account</h3>

  1. create different public key
example

$ ssh-add ~/.ssh/id_rsa_activehacker
$ ssh-add ~/.ssh/id_rsa_jexchan


you can delete all cached keys before

example

$ ssh-add -D


finally, you can check your saved keys

example

$ ssh-add -l


  1. Modify the ssh config
bash

#activehacker account
Host github.com-activehacker
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_activehacker

#jexchan account
Host github.com-jexchan
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_jexchan


<h3 id="use git through proxy">use git through proxy</h3>

<http://cms-sw.github.io/tutorial-proxy.html> How to open a SOCKS proxy
through an SSH tunnel The ssh command distributed with most Unix-like
systems can open a SOCKS proxy on the local machine and forward all
connections through the ssh tunnel. For example

example

ssh -f -N -D 1080 cmsusr.cms


will connect to the host cmsusr.cms, open a SOCKS proxy on the local
host on port 1080 (-D 1080), and put the process in background after a
successful connection (-f -N). How to connect to a git repository using
the SSH protocol

If the remote has a format like

git@github.com:cms-sw/cmssw.git <ssh://git@github.com/cms-sw/cmssw.git>

then you are connecting to the git server using the SSH protocol.

In this case, git relis on ssh to handle the connection; in order to
connect through a SOCKS proxy you have to configure ssh itself, setting
the ProxyCommand option in your ~/.ssh/config file:

Host github.com User git ProxyCommand nc -x localhost:1080 %h %p

For more information, see ssh<sub>config</sub>(5). How to connect to a
git repository using the HTTP or HTTPS protocols

If the remote has a format like

<http://github.com/cms-sw/cmssw.git>
<https://github.com/cms-sw/cmssw.git>

then you are connecting to the git server using the HTTP or HTTPS
protocols. In the old days, this used to be a dumb protocol, but since
git 1.6.6 it uses a smart protocol similar to that used by SSH or GIT.

In this case git uses libcurl to handle the connection; the version of
git bundled with CMSSW supports different kinds of proxies: SOCKS4,
SOCKS4a, SOCKS5, and HTTP/HTTPS. In order to connect through any proxy
supported by libcurl, you can set the http.proxy option:

git config –global http.proxy socks5://localhost:1080

For more information, see the –proxy option in curl(1) and the
http.proxy entry in git-config(1). How to connect to a git repository
using the GIT protocol

If the remote has a format like

<git://github.com/cms-sw/cmssw.git>

then you are connecting to the git server using the GIT protocol.

In this case, it is possible to use a helper command to connect through
any kind of proxy. A simple script is included with CMSSW, to connect
through a SOCKS5 proxy: git-proxy. You can configure git to use it with

git config –global core.gitproxy "git-proxy" git config –global
socks.proxy "localhost:1080"

For more information, see git-proxy –help.

<h3 id="Remove sensitive data">Remove sensitive data</h3>

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

<h3 id="当前路径对Git的影响">当前路径对Git的影响</h3>

Git的pull操作其实是fetch和merge的组合,git merge操作会去搜索working
tree,如果不指定参数的情况下,会在当前路径去搜索。当结合sudo来使用git时,git的这种行为会产生问题:

example

#> cd ~
#> sudo -u dmalikov git --git-dir=/home/dmalikov/path/to/repo/.git pull
/usr/libexec/git-core/git-sh-setup: line 142: cd: /root/.: Permission denied
Cannot chdir to /root/., the toplevel of the working tree


这里出现了切换路径的权限错误,究其原因是git
merge操作要从当前目录,也就是root用户所在的目录下去找,由于dmalikov用户没有切换到root用户home目录的权限,于是出现这个错误。解决办法是使用fetch:

example

sudo -u dmalikov git --git-dir=/home/dmalikov/path/to/repo/.git fetch


也可以先切换工作目录,然后再操作pull:

example

(cd /home/dmalikov/path/to/repo; sudo -u dmalikov git pull)


<h2 id="本地操作">本地操作</h2>

| Source Main Section | Destination Main Section | Action | Status |
|---------------------|--------------------------|----------------|-----------|
| Working Directory | Staging Area | Stage files | Staged |
| Staging Area | Git Directory | Commit files | Committed |
| Git Directory | Working Directory | Checkout files | Committed |

Git中的文件共有三种状态:committed,modified,staged。文件在修改以后,Stage之前的状态称为Modified。Staging
Area是git目录中的一个文件,存放了下次需要commit的信息,有时也称为index。

<h2 id="Remotes">Remotes</h2>

<h3 id="概念">概念</h3>

A remote is a reference, or handle, to another repository through a
filesystem or network path. You use a remote as a shorthand name for an
otherwise lengthy and complicated Git URL.
为了跟踪其它仓库中的数据,git使用了remote-tracking
branches。本地仓库的remote-tracking branch就是remote
repository的代理。你还可以设置local-tracking branch。 bare
repository没有检出的branch,不能在上面提交。bare
repository是协作开发的中心点,开发者通过clone和fetch操作从bare
repo中抽取数据,通过pull操作更新bare repo。bare
repo中也不会启用reflog。如果要让开发者往repo中push,那么这个repo就得是bare。

  1. git clone

原repo中refs/heads/下的branch会被复制到refs/remotes/下,而原repo中的refs/remotes并不会复制到新的repo。tag也会被clone复制过来,但像hooks,configuration
files,reflog,stash等就不会被复制过来了。
默认情况下,新clone的repo中会保留一个名为origin的链接,用来指向原repo。不过原repo可不会知道有谁连接了它。

<h3 id="常用操作">常用操作</h3>

| 命令 | 含义 |
|------------------------------------------|-------------------------------------|
| git clone URL | 将远程仓库克隆到本地目录,origin |
| git remote -v | 列出所有本地设定的remote repository |
| git remote add \[remote-name\] URL | 添加remote repository |
| git fetch \[remote-name\] | 从其他repository中抽取对象 |
| git push \[remote-name\] \[branch-name\] | 提交更改 |
| git remote show \[remote-name\] | 查看remote信息 |

<h3 id="git fetch">git fetch</h3>

从远程仓库下载数据,但不会自动合并,对本地的文件不会有任何影响,合并必须用git
merge。如果设定了本地branch track remote branch,则用git
pull命令会自动fetch并merge到当前branch。git clone会自动让本地master
branch去track remote master branch,因此git clone执行之后可用git
pull自动更新到远程repository。

<h3 id="git push">git push</h3>

如果push upstream之前已经有他人push
upstream,git会拒绝你的push,你必须再次pull
down,incorporate,然后再push upstream。

<h3 id="重置远程master到以前的提交">重置远程master到以前的提交</h3>

example

git checkout master
git reset --hard e3f1e37
git push --force origin master


example

git diff master..origin/master


<h2 id="Branch">Branch</h2>

<h3 id="概念">概念</h3>

example

git add README test.rb LICENSE2
git commit -m 'initial commit of my project'


提交以后git repository中会有如下五个对象: Single Commit Repository
Data

其中blob即为提交的文件。所谓branch,即是指向这些commit对象的轻量级的可移动的指针。说是轻量级,因为git中创建一个branch只需写入40个字节的SHA-1
checksum和1个回车符到repository的文件中。
Git默认的branch名为master,这是在commit后自动创建的。用git branch
\[branch-name\]可创建新的branch,但git
branch命令只创建,并不会切换到新的branch。Git通过一个特殊的指针HEAD来指向当前所在branch,这与Subversion的HEAD有着天壤之别。切换branch用git
checkout \[branch-name\]命令,此命令只是让HEAD指针指向新的branch。git
checkout -b \[branch-name\]是创建并切换的快捷方式,相当于git branch
\[branch-name\] ; git checkout \[branch-name\]。
切换branch是有条件的,如果index中有未解决的冲突,则无法checkout。必须在切换前解决这些冲突。

<h3 id="Merge">Merge</h3>

  1. Fast Forward
example

git checkout master
git merge hotfix


 Git Merge Fast

Forward

  1. Simple Three-Way Merge

Three-Way: two branch, the common ancestor of the two.
Git自动找出两个分支的common ancestor,以common
ancestor为合并的base,合并以后自动commit,此commit称为merge
commit。merge commit对象与一般commit对象不同之处在于它有多个parent。

Three-way merge identify common

ancestor

Three-way merge after

commit

  1. Merge Conflicts
example

git merge iss53 #如果有冲突,则会提示CONFLICT,自动merge只完成了没有冲突的部分,并且不会提交。冲突的文件中,git会添加standard conflict-resolution marker。
git status #查看需要手动merge的文件。


编辑冲突文件或用git mergetool

example

git add [conflict-file] #标记冲突已经解决
git commit #此时会显示Merge branch信息


<h3 id="Remote Branch">Remote Branch</h3>

Remote branch是一种特殊的branch,你不能去控制它,只能通过网络更新。用git
clone命令复制repository后,本地的branch结构如下: Branches after git
clone

如果要共享本地branch,则需使用push操作(subversion中完全没有这个概念,只要commit即会提交到服务器,而git没有中央服务器一说,只谈共享某个branch)。
git push origin serverfix 将本地serverfix branch共享到origin remote git
push origin serverfix:awesomebranch 将本地serverfix branch共享到origin
remote的awesomebranch branch Tracking Branch是一种特殊的local
branch,Tracking Branch知道与自己与哪个remote
branch关联,不带任何参数使用git push和git pull就能自动push和pull。git
clone后,默认本地的master即与origin/master关联。有两种方法创建Tracking
Branch:

  1. git checkout -b \[branch\] \[remotename\]/\[branch\]
  2. git checkout –track \[remotename\]/\[branch\]

删除remote branch的语法比较古怪: git push \[remotename\] :\[branch\]

<h3 id="Rebasing">Rebasing</h3>

Rebase和Merge最终的效果是一样的,不同之处在于两者的历史不同。Rebase会把两个分支上所有的操作依序排列,看起来像是线性的,而merge的历史看起来是多条线并行的。使用Rebase的原则是:决不要对已经在公共repository上发布的commit进行rebase。Rebase只可用作在push之前,用来让自己的工作更干净。

<h2 id="fetch和pull的区别">fetch和pull的区别</h2>

fetch从远程仓库取出数据,但不会自动merge到当前work
directory。而pull则包含了merge操作。

<h2 id="Rebase和Merge">Rebase和Merge</h2>

将某分支的更改整合到另一分支上,Git中可用Rebase或Merge来完成。主要区别在于:Rebase会更改历史,而Merge会保留合并的历史。

<h3 id="Rebase">Rebase</h3>

Rebase可移动某个分支,不过commit并不能被移动,rebase实际做的事情是用原来的commits的changeset和metadata创建新的commit。Rebase步骤如下:

  1. Identify the commits to be moved (more accuratedly,replicated).
  2. Compute the corresponding changesets (patches).
  3. Move HEAD to the new branch location (base).
  4. Apply the changesets in order, making new commits preserving author

information. (replaying)

  1. Finally, update the branch ref to point to the new tip commit.

<h2 id="合并git仓库">合并git仓库</h2>

bash

git remote add repo2
git fetch repo2
git co -b newb repo2/master
git mv xxx xxx (把你想移动的文件移动到你喜欢的位置)
git co master
git merge newb
git remote rm repo2


<h2 id="Hooks">Hooks</h2>

共有两类Hook,一类是client
side,发生在像commit和merge操作的时候,另一类是server side,发生在git
server接收到pushed commit的时候。

<h2 id="Internals">Internals</h2>

Git底层是content-addressable filesystem,上面加了VCS接口。
Git中这些底层的命令称为“plumbing” commands或“porcelain”
commands,一般在脚本中使用得比较多。

<h3 id="blob对象">blob对象</h3>

Git就像一个简单的key-value data store。通过plumbing command
hash-object,就能往.git目录中添加数据,并获得key。如:

example

$ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4


然后就能找到对象文件了:

example

$ find .git/objects -type f
.git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4


用cat-file命令可以查看该object的内容:

example

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content


保存文件话,无非多个参数:

example

$ echo 'version 1' > test.txt
$ git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30


这些文件内容对象称为blob,可用下面的命令来看:

example

$ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
blob


<h3 id="tree对象">tree对象</h3>

至于文件名是通过tree object来存放的。tree对象由一个或多个tree
entry组成,tree entry包含了指向blob或subtree的SHA-1指针,以及mode, type,
filename等。比如:

example

$ git cat-file -p master^{tree}


master<sup>tree</sup>表示上一个commit指向的tree对象。

<h3 id="commit对象">commit对象</h3>

blob对象存放文件内容,tree对象相当于blob和tree的容器,至于保存的时间、作者等信息就要通过commit对象来存放。

example

$ echo 'first commit' | git commit-tree d8329f
fdf4fc3344e67ab068f836878b6c4951e3b15f3d


通过查看commit对象可以看到top tree对象及作者等信息:

example

$ git cat-file -p fdf4fc3


<h3 id="tag对象">tag对象</h3>

tag对象与commit对象很相似,唯一不同在于tag对象有指针指向commit对象,而不是commit对象一样指向tree对象。
tag有两种:annotated and lightweight。lightweight
tag只是一个引用,创建后就不会再有修改。

example

$ git update-ref refs/tags/v1.0 cac0cab538b970a37ea1e769cbbde608743bc96d


annotated tag则会创建tag对象,在对象中指向commit对象。

example

$ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag'


Git中任何对象都是可以tag的。

<h3 id="remote引用">remote引用</h3>

remote引用与branch引用唯一的区别在于remote引用是只读的。可以从remote引用中checkout,但HEAD并不会指向个引用,因此无法通过commit来更改。remote引用更像是书签,Git用来记录上一次使用时的服务器分支的状态。

<h3 id="refspec">refspec</h3>

example

$ git remote add origin https://github.com/schacon/simplegit-progit


执行上面的命令后,Git会添加如下配置:

[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*

refspec的格式为:+\<src\>:\<dst\>
其中,src为远程主机上的引用,dst为本地引用,+号表示即使不是fast-forward也可更新。
远程仓库添加成功后,在本地就可访问远程各个分支的日志了,下面三条命令的效果是相同的。

example

$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master


如果要限定只同步远程master分支,那么可作如下配置:

example

fetch = +refs/heads/master:refs/remotes/origin/master


也可以通过命令行指定:

example

$ git fetch origin master:refs/remotes/origin/mymaster


push指定分支到远程master:

example

$ git push origin master:refs/heads/qa/master


也可在配置文件中添加如下行:

example

push = refs/heads/master:refs/heads/qa/master


删除远程分支:

example

$ git push origin :topic


\<src\>:\<dst\>格式中让\<src\>为空,意味着远程分支会被删除。

<h2 id="日志">日志</h2>

<h3 id="在日志中找出指定文件的操作记录">在日志中找出指定文件的操作记录</h3>

工程根目录下的README.md被删除,时间已经过去很久,要找回来。

example

git log -- README.md


找出最后修改该文件之前的commit。

example

git checkout 65d9f1a43e5830618c7693d6fef4845ed9aade85 -- README.md


再将新的文件重新提交。

<h3 id="Git代码行统计命令集">Git代码行统计命令集</h3>

统计某人的代码提交量,包括增加,删除:

example

git log --author="$(git config --get user.name)" --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "added lines: %s removed lines : %s total lines: %s\n",add,subs,loc }' -


仓库提交者排名前 5(如果看全部,去掉 head 管道即可):

example

git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 5


仓库提交者(邮箱)排名前
5:这个统计可能不会太准,因为很多人有不同的邮箱,但会使用相同的名字

example

git log --pretty=format:%ae | gawk -- '{ ++c[$0]; } END { for(cc in c) printf "%5d %s\n",c[cc],cc; }' | sort -u -n -r | head -n 5


贡献者统计:

example

git log --pretty='%aN' | sort -u | wc -l


提交数统计:

example

git log --oneline | wc -l


添加或修改的代码行数:

example

git log --stat|perl -ne 'END { print $c } $c += $1 if /(\d+) insertions/;'
git log --stat | perl -ne '$insertions += $1 if /(\d+) insertions/; $commits += 1 if /^commit /; END {print "commits: ${commits}, insertions: ${insertions}\n";}'


<h3 id="查看branch之间关系">查看branch之间关系</h3>

example

git log --graph --decorate --oneline --simplify-by-decoration --all


说明: –decorate 标记会让git log显示每个commit的引用(如:分支、tag等)
–oneline 一行显示 –simplify-by-decoration
只显示被branch或tag引用的commit –all
表示显示所有的branch,这里也可以选择,比如我指向显示分支ABC的关系,则将–all替换为branchA
branchB branchC

<h2 id="常用操作">常用操作</h2>

  1. 从其它分支中拷贝文件。
example

git checkout [branch] -- file name


<h2 id="查看某个文件的修改历史">查看某个文件的修改历史</h2>

  1. git log –pretty=oneline 文件名
  2. git show 356f6def9d3fb7f3b9032ff5aa4b9110d4cca87e

<h2 id="用githug学习git">用githug学习git</h2>

example

gem install githug

``