GIT的简单学习

参考的书籍是:”ProGit中文版”
参考链接:
http://www.tech126.com/git-fetch-pull/
http://lishicongli.blog.163.com/blog/static/1468259020132125247302/
http://blog.csdn.net/arkblue/article/details/9790129

1.GIT的三种状态和三个目录
对于被跟踪的文件,有三种状态:
已提交:committed,表示该文件已经被安全的保存在本地的数据库中了
已修改:modified,表示该文件被修改了,但是还没有提交保存
已暂存:staged,表示该文件已经被放入到暂存区,在下次提交的时候会被保存

相对的,我们会有三个工作区域:
本地数据目录:就是.git目录,用来保存元数据和对象数据库。该目录非常重要,每次克隆镜像仓库就是复制下这个目录。其它文件(比如工作目录中的数据)可以由这个目录中的某个版本生成
工作目录:一个存放着从项目中的某个版本取出的所有文件和目录的目录,以后的开发就是在这个目录上来弄的(也就是普通的目录)
暂存区域:就是一个简单的文件,一般也存在.git目录中

基本的工作流程是:
1.对工作目录中修改了某些文件
2.对这些修改了的文件做了快照,保存在暂存目录中
3.提交更新,将暂存目录中的文件保存到git目录中

2.安装git

[root@OS_DEV ~]# yum install git

3.git的简单配置
几个配置文件:
/etc/gitconfig:对所有用户都适用。如果git config使用了–system选项,那么读写的就是这个文件
~/.gitconfig:对特定用户适用。如果git config使用了–global选项,那么读写的就是这个文件
.git/config:对当前项目有效。

覆盖顺序的话是越小的覆盖越大的。

首先配置下个人的信息,每次提交的时候就知道是谁提交了。同时也可以设置下diff工具:

[root@OS_DEV gitlearn]# git config --global user.name "thuanqin"
[root@OS_DEV gitlearn]# git config --global user.email 646543317@qq.com
[root@OS_DEV ~]# git config --global merge.tool vimdiff

查看配置信息(如果看到了重复行,说明来自不同的文件,以最后一个为准):

[root@OS_DEV ~]# git config --list
user.name=thuanqin
user.email=646543317@qq.com
merge.tool=vimdiff

4.git基础命令
获取git的代码仓库有两种方法。一种是在现存的目录下生成一个新的git仓库(所以现存目录下的文件都需要导入到.git中)。还有一种是从已有的git仓库中clone一个。

4.1 先看从现存目录中初始化一个新的:
现在目录是这样的:

[root@OS_DEV gitlearn]# pwd
/root/gitlearn
[root@OS_DEV gitlearn]# cat readme.txt 
I'm learning Git now.
[root@OS_DEV gitlearn]# ls -a
.  ..  readme.txt

在项目的根目录执行:

[root@OS_DEV gitlearn]# git init
Initialized empty Git repository in /root/gitlearn/.git/
[root@OS_DEV gitlearn]# ls -a
.  ..  .git  readme.txt

可以发现多了一个.git的目录。由于我们还没有开始跟踪对应的文件,所以现在这个目录里边只是按照模板把对应的几个目录结构设置好。

现在我们让git跟踪我们的readme.txt文件,同时提交到git本地数据目录。通过git add命令和git commit命令:

[root@OS_DEV gitlearn]# git add readme.txt 
[root@OS_DEV gitlearn]# git commit -m 'initial project version'
[master (root-commit) 0ca7fff] initial project version
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 readme.txt

4.2 从远程clone一个
clone的意思是把远程的git目录完全的拷贝下来,因此可以看到远程git项目的所有历史、所有版本。
命令为:

git clone git://github.com/schacon/grit.git mygrit

这个命令会复制远程的.git到当前的mygrit目录,然后从.git中把最新的版本还原出来,还原到工作目录。

4.3 记录修改
在第一点中小秦我说过,对于跟踪过的文件有三种状态。其实在工作目录中,所有的文件又分为两大类:被跟踪的和未被跟踪的。比如clone一个远程的,那么所有的文件肯定都是被跟踪的(因为这些文件是从.git中还原出来的)。

如果对某个被跟踪的文件进行了修改,那么git就会把这个文件标记为已修改。通过git add命令可以把这个文件放到暂存区,然后通过git commit命令可以把暂存区的文件放到本地git目录中,这个时候这些文件的状态就变成了未修改。

可以通过下面命令查看当前被跟踪的文件的状态(下面这个表明我们没有未跟踪的文件,并且所有被跟踪的文件都是未修改的):

[root@OS_DEV gitlearn]# git status

来建立一个文件,然后看看状态,可以看到git发现有一个文件没有被跟踪:

[root@OS_DEV gitlearn]# vi helloworld.py
[root@OS_DEV gitlearn]# cat helloworld.py 
print "hello world!"
[root@OS_DEV gitlearn]# git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	helloworld.py
nothing added to commit but untracked files present (use "git add" to track)

现在把这个文件纳入跟踪,可以看到这个文件已经被加入到暂存区了,但是还没有被提交:

[root@OS_DEV gitlearn]# git add helloworld.py 
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   helloworld.py
#

现在修改一下readme.txt,看看会发生什么:

[root@OS_DEV gitlearn]# cat readme.txt 
I'm learning Git now.
I'm learning Git now.
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   helloworld.py
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   readme.txt
#

可以看到,readme.txt处于已修改状态。这个时候也需要使用git add加入到暂存区。这也就说明了git add如果用在一个未跟踪的文件上,那么就会把这个文件纳入跟踪,同时加入暂存区。如果用于一个已经被跟踪的文件身上,那么这个文件就仅仅是加入暂存区。

通过下面命令加入暂存区:

[root@OS_DEV gitlearn]# git add readme.txt 
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   helloworld.py
#	modified:   readme.txt
#

这个时候我们先不提交,再次修改一下readme.txt,看看会变成啥样:

[root@OS_DEV gitlearn]# cat readme.txt 
I'm learning Git now.
I'm learning Git now.
I'm learning Git now.
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   helloworld.py
#	modified:   readme.txt
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   readme.txt
#

可以看到readme.txt出现了两次。这个就说明了git add一个文件后,放在暂存区的是git add那个时间点的那个文件,之后哪怕再次修改了那个文件,只要不再次add它,那么这个时候commit的就是git add的那个时间点的文件,而不是最新的文件。如果要commit最新的,需要再次add:

[root@OS_DEV gitlearn]# git add readme.txt 
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   helloworld.py
#	modified:   readme.txt
#

4.4 忽略文件
对于一些临时文件我们是不需要保存的。因此可以写一个.gitignore文件,列出需要忽略的文件,如:

[root@OS_DEV gitlearn]# cat .gitignore 
*~
*.[oa]

别忘了把这个.gitignore也加入到我们的跟踪列表中:

[root@OS_DEV gitlearn]# git add .gitignore 
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   .gitignore
#	new file:   helloworld.py
#	modified:   readme.txt
#

4.5 查看差异
如果直接运行git diff,可以看到没有加入到暂存区的被跟踪文件(就是已修改)和上次提交时候的差异(所以如果被加入暂存区的,那么这里看到的是空的)。
如果运行git diff –cached或git diff –staged,可以看到加入到暂存区的被跟踪文件和上次提交时候的差异(所以如果没有被加入暂存区,那么这里看到的是空的)。

4.6 提交跟新
git commit可以提交跟新。如果没有加-m参数指明说明,那么会使用系统默认的编辑器让你输入这个新版本的说明(当然这个编辑器是可以设置的):

[root@OS_DEV gitlearn]# git commit
[master 76064c7] Learn git commit command
 3 files changed, 5 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore
 create mode 100644 helloworld.py
[root@OS_DEV gitlearn]# 

解释一下这里的输出:master表示branch。76064c7是本次提交的完整校验。”Learn git commit command”是写的注释。下面则是相关的具体内容。

4.7 直接提交更新,不使用暂存区
通过下面的命令可以直接提交更新,而不是用暂存区(但前提是这些文件已经被跟踪了):

[root@OS_DEV gitlearn]# echo "A new file" > new.txt
[root@OS_DEV gitlearn]# git commit -a -m "add a new file"
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	new.txt
nothing added to commit but untracked files present (use "git add" to track)
[root@OS_DEV gitlearn]# git add new.txt 
[root@OS_DEV gitlearn]# git commit -a -m "add a new file"
[master ebe4a7c] add a new file
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 new.txt

4.8 移除文件(rm)
就是让这个文件不被git管理(也就是不跟踪了)

[root@OS_DEV gitlearn]# git status
# On branch master
nothing to commit (working directory clean)
[root@OS_DEV gitlearn]# rm new.txt 
rm: remove regular file `new.txt'? y
[root@OS_DEV gitlearn]# git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	deleted:    new.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@OS_DEV gitlearn]# git rm new.txt
rm 'new.txt'
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    new.txt
#
[root@OS_DEV gitlearn]# git commit -m "rm new.txt"
[master 6cf39f6] rm new.txt
 1 files changed, 0 insertions(+), 1 deletions(-)
 delete mode 100644 new.txt
[root@OS_DEV gitlearn]# git status
# On branch master
nothing to commit (working directory clean)

如果这个文件在rm之前被加入到了暂存区(并且它也被修改了),那么删除的时候需要加-f参数。

还有一种情况是我们想把文件不被跟踪,但是呢不想从当前目录下删除(上面的那个需要先rm对应的文件才行)。这个时候只需要这样就行了:

[root@OS_DEV gitlearn]# git status
# On branch master
nothing to commit (working directory clean)
[root@OS_DEV gitlearn]# git rm --cached helloworld.py
rm 'helloworld.py'
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    helloworld.py
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	helloworld.py

可以看到,helloworld.py变成了未被跟踪的状态了。同时暂存区的该文件变成了待删除状态。

4.9 移动文件(mv)
通过下面三个命令可以实现:

[root@OS_DEV gitlearn]# git mv readme.txt readme_rename.txt 
[root@OS_DEV gitlearn]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    helloworld.py
#	renamed:    readme.txt -> readme_rename.txt
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	helloworld.py

helloworld.py我们不去看它。这个时候只要commit一下就可以了:

[root@OS_DEV gitlearn]# git commit -m "rename readme.txt to readme_rename.txt"
[master 3773ad1] rename readme.txt to readme_rename.txt
 2 files changed, 0 insertions(+), 1 deletions(-)
 delete mode 100644 helloworld.py
 rename readme.txt => readme_rename.txt (100%)
[root@OS_DEV gitlearn]# git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	helloworld.py
nothing added to commit but untracked files present (use "git add" to track)

其实刚刚的几个命令相当于:

$ mv readme.txt readme_rename.txt
$ git rm readme.txt
$ git add readme_rename.txt

如果直接commit会发生什么呢:

[root@OS_DEV gitlearn]# git status
# On branch master
nothing to commit (working directory clean)
[root@OS_DEV gitlearn]# mv readme_rename.txt readme_rename_rename.txt 
[root@OS_DEV gitlearn]# git status
# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	deleted:    readme_rename.txt
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	readme_rename_rename.txt
no changes added to commit (use "git add" and/or "git commit -a")

这时我们就需要手工git rm和git add了。如果使用某种工具批量的移动了文件,那么这个时候就只能手工的执行git rm先把这些文件移出跟踪列表,然后再git add加入重命名后的文件了。

4.10 查看提交历史
先远程clone一个书中的例子:

[root@OS_DEV ~]# git clone git://github.com/schacon/simplegit-progit.git
Initialized empty Git repository in /root/simplegit-progit/.git/
remote: Reusing existing pack: 13, done.
remote: Total 13 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (13/13), done.
Resolving deltas: 100% (3/3), done.
[root@OS_DEV ~]# cd simplegit-progit/
[root@OS_DEV simplegit-progit]# ls
lib  Rakefile  README
[root@OS_DEV simplegit-progit]# 

使用git log,查看提交历史:

[root@OS_DEV simplegit-progit]# git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gmail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the verison number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test code

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

git log的一些参数的使用:
-p:显示每次提交的差异,会使用默认的编辑器打开(比如vi):

[root@OS_DEV simplegit-progit]# git log -p

-NUMBER:显示多少个提交记录,NUMBER是一个数字,比如-2表示显示最近的两个:

[root@OS_DEV simplegit-progit]# git log -p -2

–stat:只显示写统计信息:

[root@OS_DEV simplegit-progit]# git log -p -2 --stat

–pretty:显示的格式可以做些改变,有很多的参数,比如oneline就是显示成一行:

[root@OS_DEV simplegit-progit]# git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the verison number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

另外配合format,可以显示自定义的格式。

–graph:显示分支和合并情况:

[root@OS_DEV simplegit-progit]# git log --pretty=format:"%h %s" --graph
* ca82a6d changed the verison number
* 085bb3b removed unnecessary test code
* a11bef0 first commit

4.11 撤销
1.取消暂存的文件(就是文件已经被git add了):

[root@OS_DEV simplegit-progit]# echo "This a new file" > new.txt
[root@OS_DEV simplegit-progit]# git add new.txt 
[root@OS_DEV simplegit-progit]# git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   new.txt
#

通过这个命令可以从暂存区移除这个文件:

[root@OS_DEV simplegit-progit]# git reset HEAD  new.txt

2.取消对文件的修改(就是还没有被git add,但是修改过了,我想取消这些修改):

[root@OS_DEV simplegit-progit]# git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
[root@OS_DEV simplegit-progit]# cat new.txt 
This a new file
[root@OS_DEV simplegit-progit]# echo "Hi, git" > new.txt
[root@OS_DEV simplegit-progit]# git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   new.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[root@OS_DEV simplegit-progit]# git checkout -- new.txt
[root@OS_DEV simplegit-progit]# cat new.txt 
This a new file
[root@OS_DEV simplegit-progit]# git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

4.12 远程仓库
1.查看
通过git remote命令可以查看当前配置的远程git仓库。在clone某个项目后,至少可以看到一个origin的远程库。git默认使用这个origin来标识所克隆的原始库:

[root@OS_DEV ~]# git clone git://github.com/schacon/ticgit.git
Initialized empty Git repository in /root/ticgit/.git/
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 108 KiB/s, done.
Resolving deltas: 100% (772/772), done.
[root@OS_DEV ~]# cd ticgit/
[root@OS_DEV ticgit]# git remote
origin
[root@OS_DEV ticgit]# git remote -v
origin	git://github.com/schacon/ticgit.git (fetch)
origin	git://github.com/schacon/ticgit.git (push)

再详细说下这个origin,具体的知识可以看一开始贴出来的参考链接,下面的很多是从这个链接中复制过来的:
对git的操作是围绕3个大的步骤来展开的:
1. 从git取数据(git clone)
2. 改动代码
3. 将改动传回git(git push)
这3个步骤又涉及到两个repository,一个是remote repository,再远程服务器上,一个是local repository,再自己工作区上。其中
1, 3两个步骤涉及到remote server/remote repository/remote branch,
2涉及到local repository/local branch。git clone 会根据你指定的remote server/repository/branch,拷贝一个副本到你本地,再git push之前,你对所有文件的改动都是在你自己本地的local repository来做的,你的改动(local branch)和remote branch是独立(并行)的。
在clone完成之后,Git 会自动为你将此远程仓库命名为origin(origin只相当于一个别名,运行git remote –v或者查看.git/config可以看到origin的含义),并下载其中所有的数据,建立一个指向它的master 分支的指针,我们用(远程仓库名)/(分支名) 这样的形式表示远程分支,所以origin/master指向的是一个remote branch(从那个branch我们clone数据到本地),但你无法在本地更改其数据。
同时,Git 会建立一个属于你自己的本地master 分支,它指向的是你刚刚从remote server传到你本地的副本。随着你不断的改动文件,git add, git commit,master的指向会自动移动。
对于git branch -a 命令,如果前面显示的是remote/XXX,那么这个repository就是远程的,不在本地。如果没有remote,那么就是本地的,比如:

[root@OS_DEV ticgit]# git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/ticgit
  remotes/pb/master
  remotes/pb/ticgit

这里远程有两个库(origin和pb),每个库(其实库可以看成是一个git文件)都有master和ticgit两个分支。本地有一个master库,默认是clone的时候从remotes/origin/master拿下来的。
git diff origin/master master这个命令可以看远程的master和本地的区别。

2.添加远程仓库

[root@OS_DEV ticgit]# git remote add pb git://github.com/paulboone/ticgit.git
[root@OS_DEV ticgit]# git remote
origin
pb

3.git fetch
从远程的分支获取最新的版本到本地。还有一个类似的命令是git pull。
git fetch:相当于是从远程获取最新版本到本地(在本地会有一个remote/origin/master,就是远程的拷贝),不会自动merge:

[root@OS_DEV ~]# git clone git://github.com/schacon/ticgit.git
Initialized empty Git repository in /root/ticgit/.git/
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 112 KiB/s, done.
Resolving deltas: 100% (772/772), done.
[root@OS_DEV ~]# cd ticgit/
[root@OS_DEV ticgit]# git remote -v
origin	git://github.com/schacon/ticgit.git (fetch)
origin	git://github.com/schacon/ticgit.git (push)
[root@OS_DEV ticgit]# git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/ticgit
[root@OS_DEV ticgit]# git diff master remotes/origin/master
[root@OS_DEV ticgit]# 

4.git push
可以将本地仓库中的数据推送到远程仓库。实现这个任务的命令很简单: git push [remote-name] [branch-name]。如果要把本地的master 分支推送到origin 服务器上(再次说明下,克隆操作会自动使用默认的master 和origin 名字),可以运行下面的命令:

git push origin master

只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,并到自己的项目中,然后才可以再次推送。

5.查看远程仓库的详细信息

[root@OS_DEV ticgit]# git remote show origin
* remote origin
  Fetch URL: git://github.com/schacon/ticgit.git
  Push  URL: git://github.com/schacon/ticgit.git
  HEAD branch: master
  Remote branches:
    master tracked
    ticgit tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

可以看到,remote上有连个分支master和ticgit,如果执行pull的话会的merge到本地的master上。

6.总结
我在服务器A上有一个项目PROJECTA.git,我从B上可以clone一个下来,这个时候B执行clone命令,clone命令就是从A那里把PROJECTA.git下载下来,把这个git标记为origin,同时从这个git中恢复一个最新的版本,恢复到本地新建立的git库中的master分支上。在本地看PROJECTA.git的话默认看到的是叫做origin这个名字。如果现在A上的项目没人提交,本地的master也没人动过,那么B上的master和B上的origin/master(也就是A上的master)是一样的。
那如果A上有人跟新了,我想把东西pull下来那是怎么一个情况呢?其实就是git fetch origin master,这个就是把origin的master拿下来,拿到哪里呢?拿到本地的origin/master上。那么如何合并到我本地的master呢?merge本地的master和origin/master就行了。
那如果服务器C上也有个项目,和这个一样,我也想去看看我本地的master和他的区别,应该咋办呢?很简单,fetch到本地(比如不叫origin了,改名叫remoteC),这个时候本地就能看到remote/remoteC这个git库了,另外应该也能看到remote/remoteC/master这个branch。然后我git diff master remoteC/master去看看有没有啥区别,就知道C上的人做了些啥了。

4.13 标签tag
对某一时间点上的版本打上标签。在发布某个软件版本(比如v1.0 等等)的时候,经常这么做。

通过git tag可以查看标签:

[root@OS_DEV ticgit]# git tag
[root@OS_DEV ticgit]# 

建立标签(其实就是对某一个时间点的commit的记录做个记录):

[root@OS_DEV ticgit]# git tag -a v1.4 -m 'my version 1.4'
[root@OS_DEV ticgit]# git tag
v1.4

查看详细点的信息:

[root@OS_DEV ticgit]# git tag
v1.4
[root@OS_DEV ticgit]# git show v1.4
tag v1.4
Tagger: thuanqin <646543317@qq.com>
Date:   Sun Apr 20 07:49:59 2014 -0700

my version 1.4

commit 847256809a3d518cd36b8f81859401416fe8d945
Author: Jeff Welling <Jeff.Welling@Gmail.com>
Date:   Tue Apr 26 17:29:17 2011 -0700

    Added note to clarify which is the canonical TicGit-ng repo

diff --git a/README.mkd b/README.mkd
index ab92035..9ea9ff9 100644
--- a/README.mkd
+++ b/README.mkd
@@ -1,3 +1,6 @@
+Note: the original TicGit author has pulled all the TicGit-ng changes into his repository, creating a potentially confusing situation. The schacon TicGit repo, this one, is not consistently 
+https://github.com/jeffWelling/ticgit
+
 ## TicGit-ng ##
 
 This project provides a ticketing system built on Git that is kept in a

5.分支branch
创建和查看分支:

[root@OS_DEV ticgit]# git branch aaa
[root@OS_DEV ticgit]# git branch -a
  aaa
* master
  remotes/origin/master
  temp
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/ticgit

其实分支就是一个指针。当前分支由HEAD这个指针指明。

切换分支用git checkout XXX:

[root@OS_DEV ticgit]# git checkout aaa

如果想要新建一个分支并直接切换过去,那么:

[root@OS_DEV ticgit]# git checkout -b ccc

删除分支:

[root@OS_DEV ticgit]# git branch -d aaa

合并分支:
通过merge,将merge的那个参数指明的分支合并到当前分支,比如:

$ git checkout master
$ git merge hotfix

这里有一个概念叫做”Fast forward”,,如果顺着一个分支走下去可以到达另一个分支,那么Git 在合并两者时,只会简单地把指针前移,因为没有什么分歧需要解决,所以这个过程叫做快进(Fast forward)

跟踪分支:
从远程分支检出的本地分支,称为跟踪分支(tracking branch)。跟踪分支是一种和远程分支有直接联系的本地分支。在跟踪分支里输入git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在这些分支里运行git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来。

在克隆仓库时,Git 通常会自动创建一个名为 master 的分支来跟踪 origin/master。这正是git push 和 git pull 一开始就能正常工作的原因。当然,你可以随心所欲地设定为其它跟踪分支,比如origin 上除了 master 之外的其它分支。刚才我们已经看到了这样的一个例子:git checkout -b [分支名] [远程名]/[分支名]。
如果你有1.6.2 以上版本的Git,还可以用–track 选项简化:

[root@OS_DEV keystone]# git checkout --track -b myhavana origin/stable/havana
Branch myhavana set up to track remote branch stable/havana from origin.
Switched to a new branch 'myhavana'
[root@OS_DEV keystone]# git pull #或者[root@OS_DEV keystone]# git pull origin stable/havana
Already up-to-date.
[root@OS_DEV keystone]# git branch -v -a
* icehouse                        6b942ed delete tox.ini
  master                          0773c4e Merge "Remove LDAP password hashing code"
  myhavana                        e364ba5 Sanitizes authentication methods received in requests.
  stable/icehouse                 1e94804 Opening stable/icehouse
  remotes/origin/HEAD             -> origin/master
  remotes/origin/feature/key-dist cf20a1a Merge "SQLAlchemy Change to support more strict dialect checking"
  remotes/origin/master           0773c4e Merge "Remove LDAP password hashing code"
  remotes/origin/stable/havana    e364ba5 Sanitizes authentication methods received in requests.
  remotes/origin/stable/icehouse  1e94804 Opening stable/icehouse

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*