LINUX GIT 使用

git show HEAD
git show HEAD^
git show HEAD^^
git show HEAD^^^


git diff 486ec madplay/player.c
git diff 4863  856f

git diff 4863:libmad/mad.h 856f:/libmad/mad.h


git-whatchanged utils/audio.sh  列出有哪些版本改动了utils/audio.sh

git-whatchanged -p utils/audio.sh 列出有哪些版本改动了utils/audio.sh并

一一diff

git diff >patch.diff

git -apply -R < ./xxx.diff.patch



git checkout -f丢失本地一切改动,回来树上最新的状态

你可能还想看到每一步改进中的所有完整的 diff ,这可以使用如下命令

$ git log -p

浏览改动的概要对于获得每一步修改的情况常常是比较有用的,可以使用如下

命令

$ git log --stat --summary



git 简要教程
2009-06-02 20:09

原文链接:

http://www.kernel.org/pub/software/scm/git/docs/tutorial.html

这个教程将介绍如何将一个新的项目导入到 git 之中,如何修改项目并如何将

这些变更与其他开发者分享。

如果你更感兴趣如何用 git 取出一个项目,比如,测试软件的最新版本,你可

能更应该看看 The Git User's Manual 的前两章。

首先,记住你可以用 man 来获取 git 的文档,比如 "git diff" 的文档可以用如

下命令察看:

$ man git-diff

在做任何改动之前,最好把自己的名字和 email 地址介绍给大家,最简单的方

法就是:

$ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com

导入一个新项目

假设你有一个名为 project.tar.gz 的 tarball 作为项目的初始内容。你可以如下

操作来把它至于 git 版本控制之下。

$ tar xzf project.tar.gz
$ cd project
$ git init

Git 将会如下回复:

Initialized empty Git repository in .git/

现在,你已经初始化了工作目录——你可能已经注意到了名为 ".git" 的一个新目

录了。下一步就是使用 git-add(1) 命令告诉 git 当前目录的所有文件全是项目

的一个快照:

$ git add .

这个快照目前存放在一个临时区域之中,在 git 中称为 "index"。使用 git-

commit 命令,你可以把 index 的所有内容永久性地存放到软件仓库之中:

$ git commit

这条命令会向你提示输入版本变更信息。这样,你的项目的第一个版本就已经

存入 git 之中了。
进行修改

修改一些文件之后,你可以将

更新这些内容到 index 之中:

$ git add file1 file2 file3

现在,你已经准备就绪,可以提交了。现在你可以使用 git-diff(1) 命令的 --

cache 参数

来查看都有哪些内容将会被提交:

$ git diff --cached

(如果不使用 --cached 参数,git-diff(1) 会显示所有还没添加进 index 的已经

做出的改动。) 你也可以使用 git-status (1) 来获得一些当前状况的概要信息:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   file1
#       modified:   file2
#       modified:   file3
#

如果你需要进行更多改动,现在就可以进行,然后可以添加到 index 之中。最

后,使用如下命令提交改动:

$ git commit

这将再次要求你输入关于这次改动内容的描述性信息,之后记录下

的项目新版本。此外,如果想省掉提交之前的 git add 命令,你可以直接用

$ git commit -a

这样会自动检测所有修改过的文件 (不包括新文件) ,并一气呵成地将它们添到

index 之中,并提交。

关于提交的描述信息: 虽然这个信息不是必须的,但提交信息描述最好以一行不

超过50个字符的概要性信息来开头,在一个空行之后再进行更多的描述。比如

那些将 commit 转化为 email 的工具就会把这个第一行作为邮件标题,其余的

提交内容则放在邮件内部。
Git 跟踪内容而不是文件

很多版本控制系统提供了一个 "add" 命令用来记录一个新文件。而 git 的

"add" 命令更加简单也更加强大: git-add 既用于新文件也用于新近改动的文件

,在所有这些情况下,它在 index 中对所有的文件与状态进行一次快照,这样

就可以在下一次 commit 命令中进行提交。
查看项目历史

在任何时候,你都可以如下查看所有你进行过的改动

$ git log

你可能还想看到每一步改进中的所有完整的 diff ,这可以使用如下命令

$ git log -p

浏览改动的概要对于获得每一步修改的情况常常是比较有用的,可以使用如下

命令

$ git log --stat --summary

管理分支

一个 git 仓库可以包含多个开发分支。使用如下命令可以建立一个称为

"experimental" 的新分支

$ git branch experimental

如果你运行命令

$ git branch

你将可以得到类似下面的已有分支的列表

  experimental
* master

"experimental" 就是你刚刚建立的那个分支,而 "master" 分支则是建立仓库

的时候自动创建的缺省分支,里面的星号表示你当前所在的分支;输入命令

$ git checkout experimental

就可以切换到 experimental 分支。现在修改一个文件,并提交改变,然后重

新回到 master 分支:

(edit file)
$ git commit -a
$ git checkout master

你会发现,刚才的变更已经不可见了,这是因为这个改变是发生于

experimental 分支的,而你现在已经回到 master 分支了。

(edit file)
$ git commit -a

这里,两个分支已经产生不同了,每个分支上都发生了不同的改动。要把

experimental 中的改变也合并到 master 之中,运行命令

$ git merge experimental

如果两者的改变并不冲突,那么就算是完成了。而如果这里有冲突,有问题的

文件左边会显示出标记,以表明这个文件发生了冲突;

$ git diff

上述命令将会列出具体的冲突。一旦你编辑文件解决了冲突,

$ git commit -a

这个命令将把合并的结果提交。最终,

$ gitk

会显示出漂亮的图标以展示历史变革。

这里你可以使用如下命令删除 experimental 分支。

$ git branch -d experimental

这个命令会确定 experimental 中的所有改动已经在当前分支当中了。

如果你在 crazy-idea 分支中进行开发,然后又后悔了,你可以用如下命令删除

分支

$ git branch -D crazy-idea

分支操作十分简单而且代价低廉,所以适合于尝试一些东西。
使用 git 进行协作

假设 Alice 在 /home/alice/project 中的 git 仓库启动了一个新项目,而在本

机中也拥有 home 目录的 Bob 想要贡献一些代码。

他可以以如下工作开始:

$ git clone /home/alice/project myrepo

这会新建一个名为 "myrepo" 的目录,里面包含了 Alice 的仓库的一份克隆。

这份克隆与原始项目完全一致,可以处理自己的一份原始项目历史。

之后,Bob 进行了一些变更并提交了这些变动:

(edit files)
$ git commit -a
(repeat as necessary)

当他完成的时候,他告诉 Alice 将 /home/bob/myrepo 之中的变动导入到原

始仓库之中。她使用如下命令来完成这一工作:

$ cd /home/alice/project
$ git pull /home/bob/myrepo master

这 回合并 Bob 的 "master" 分支到 Alice 的当前分支。如果 Alice 也已经修改

了某些内容,她需要手工修复冲突。(注意,"master" 参数实际上并不是必要

的,因为这是缺省分支。) "pull" 命令包括两个操作: 从远端分支中取出改动,

然后合并到当前分支之中。

当你只在一个很小的小组里工作的时候,通常不会频繁地访问同一个仓库。通

过定义仓库的快捷方式,可以让访问远程仓库更方便一些:

$ git remote add bob /home/bob/myrepo

这样,你可以如下用 "git fetch" 命令仅取出改动,而不把它们合并到当前分支

之中:

$ git fetch bob

和长格式不同,当 Alice 使用 git remote 设置的快捷方式从 Bob 的仓库中获

取内容的时候,取出的内容存储在一个 remote tracking 分支之中,在本例中

是 bob/master。所以,如下操作

$ git log -p master..bob/master

将会列出从 Bob 从 Alice 的主分支中分支出去以后的所有改动。

$ git merge bob/master

这个合并也可以通过从自己的 remote tracking 分支中 pull 来做到,如

$ git pull . remotes/bob/master

注意,git pull 总是合并进当前的分支,不论命令行给出的是什么。

之后,Bob 可以如下使用 Alice 的最近改动更新自己的仓库

$ git pull

这里,他不需要给出 Alice 的仓库的位置;当 Bob 克隆了 Alice 的仓库的时候

,git 在仓库设置中保存了她的仓库的位置,即 pull 所使用的位置:

$ git config --get remote.origin.url
/home/bob/myrepo

(git-clone 创建的完整配置信息可以用 "git config -l" 获得,git-config(1) 的

man page 解释了所有选项的含义。)

Git 也在 "origin/master" 分支保存了一份 Alice 的主分支的原始拷贝:

$ git branch -r
  origin/master

如果其后 Bob 决定转到另一台主机上工作,他还可以通过 ssh 来克隆原始仓库

:

$ git clone alice.org:/home/alice/project myrepo

此外,git 本身也有远程协议,并且可以使用 rsync 或 http,详细情况可以查

看 git-pull(1) 的 man page。

Git 也可以使用类似 CVS 的工作方式,使用一个中心仓库,所有用户将改动推

送到仓库之中,相关内容可以查阅 git-push(1) 的手册页或 git for CVS users


浏览历史

Git 的历史是通过一系列相互关联的 commit 构成的。我们已经通过 git log 命

令看到了这些提交的列表。注意,每个 git log 条目的第一行是那次提交的名称

:

$ git log
commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
Author: Junio C Hamano <junkio@cox.net>
Date:   Tue May 16 17:18:22 2006 -0700

    merge-base: Clarify the comments on post processing.

把这个名称用于 git show 命令,可以得到提交的详情。

$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7

不过还有其他办法来指代这次提交。你可以只使用名称的开始部分,只要它足

够长,保证在所有提交中是惟一的就行了:

$ git show c82a22c39c   # the first few characters of the name are
                        # usually enough
$ git show HEAD         # the tip of the current branch
$ git show experimental # the tip of the "experimental" branch

每一次提交通常都有一次提交作为 "parent" ,它是项目的前一个状态:

$ git show HEAD^  # to see the parent of HEAD
$ git show HEAD^^ # to see the grandparent of HEAD
$ git show HEAD~4 # to see the great-great grandparent of HEAD

Note that merge commits may have more than one parent:

要注意,合并提交可能会有多个 "parent":

$ git show HEAD^1 # show the first parent of HEAD (same as HEAD^)
$ git show HEAD^2 # show the second parent of HEAD

你还可以给你的提交一个名字; 命令

$ git-tag v2.5 1b2e1d63ff

让你可以使用 "v2.5" 来指代 1b2e1d63ff。如果你想把这个名字与他人共享 (

比如标记一个发布版本),你应该建立一个 "tag" 对象,可能还需要签署它; 详

情请查看 git-tag(1) 的 man page。

任何 git 命令都可以使用上述任何一种名字。比如:

$ git diff v2.5 HEAD     # compare the current HEAD to v2.5
$ git branch stable v2.5 # start a new branch named "stable" based
                         # at v2.5
$ git reset --hard HEAD^ # reset your current branch and working
                         # directory to its state at HEAD^

小 心使用上述最后一个命令: 这将丢失工作目录中的所有改动,他还会清除本

分支内随后的所有提交。如果这个分支是包含这些提交的惟一分支,它们将永

远地丢失了。此外,不要对一个公众可见的、有其他开发者从中 pull 内容的分

支使用 "git reset" 命令,这将导致一些不必要的合并来清除其他开发者的历史

信息。如果你需要取消已经推送的改动,可以使用 git-revert(1) 命令。

git grep 可以在项目的所有版本历史中寻找字符串,而如下命令

$ git grep "hello" v2.5

会在版本 v2.5 中寻找所有 "hello" 的踪迹。

如果你不提供 commit 名称,git grep 会在你当前的目录中搜索所有由 git 管

理的文件。于是,如下命令

$ git grep "hello"

是搜索 git 跟踪的所有文件的便捷的方式。

很多 git 命令可以处理一组提交,可以通过多种方式来指定版本。这里是一些

git log 的例子:

$ git log v2.5..v2.6            # commits between v2.5 and v2.6
$ git log v2.5..                # commits since v2.5
$ git log --since="2 weeks ago" # commits from the last 2 weeks
$ git log v2.5.. Makefile       # commits since v2.5 which modify
                                # Makefile

你给出的范围的起始值不一定比终止值更老,比如,"stable-release" 分支可

能会在 "master" 分支之后相当长一段时间才会引入同一个提交内容,这样

$ git log stable..experimental

将会列出 expermental 分支之中已经有的,而 stable 分支却还没有的提交,

而命令

$ git log experimental..stable

将会列出 stable 中已有、但 experimental 却没有的提交。

"git log" 命令有一个弱点:必须将所有提交在一个列表中呈现出来。当项目历

史中有多个不同开发分支并最终合并到一起时,"git log" 中呈现出来的顺序可

能没什么意义。

大部分有大量开发者的项目 (比如 linux kernel 或 git 本身) 都经常合并分支,

gitk 可以更好地将这些合并变化展示出来。比如,

$ gitk --since="2 weeks ago" drivers/

这个命令允许你浏览过去两个星期中在 "drivers" 目录之中的任意提交。(注意:

你可以按住 ctrl 键然后用 "-" 和 "+" 来调整 gitk 的字体大小。)

最后,大部分命令可以带有文件名,这可以用于指定某次提交中的某个文件,

从而指定某个文件的某个版本:

$ git diff v2.5:Makefile HEAD:Makefile.in

你还可以用 "git show" 命令去查看任意文件的任意版本:

$ git show v2.5:Makefile

下一步学习

这个教程应该足够你的项目进行基本的项目发布版本管理。不过,要完全深入

地理解 git 的强大功能可能还需要理解两个简单的概念:

    * 对象数据库是个相当阳春的系统,用于存储你的项目的历史,包括文件、

目录以及各次提交。
    * 索引文件是目录树的状态的缓存,用于建立提交、取出工作目录并保存一

次合并中包含的不同的目录树。

本教程的第二部分 解释了对象数据库、索引文件以及一些其他你在使用 git 中

所需要了解的零七八碎的概念。

如果你不想在这条路上继续下去,还有一些细枝末节的东西可能十分有趣:

    *

      git-format-patch(1), git-am(1): 用于将一系列 git 提交转化成 email 发

送的补丁或反之,对于 linux 内核这样的高度依赖于邮件发送的补丁的项目来

说十分有用。
    * git-bisect(1): 当你的项目发生倒退的时候,一个跟踪发现错误的方法就是

通过历史发现那个罪魁祸首的提交。Git bisect 可以帮助你进行二分查找发现

那个提交。它能在一个有很多分支合并的具有复杂非线性历史的项目中十分灵

巧地进行接近最优的搜索。
    *

      Everyday GIT with 20 Commands Or So
    *

      git for CVS users

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值