基本的 Git 工作流程如下所示: 1. 在工作目录中修改某些文件。 2. 对这些修改了的文件作快照,并保存到暂存区域。 3. 提交更新,将保存在暂存区域的文件快照转储到 git 目录中。
2. 如何安装Git
3. 初次运行 Git 前的配置 • /etc/gitconfig文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
$ git config --global user.name "zhongwencool" $ git config --global user.email zhongwencool@gmail.com如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。 如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config文件里。 3.2 文本编辑器
$ git config --global core.editor emacs
3.3 差异分析工具
$ git config --global merge.tool vimdiffGit 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 3.4 查看配置信息
$ git config --list有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。 3.5 获取帮助 想了解 Git 的各式工具该怎么用,可以阅读它们的使用帮助,方法有三:
$ git help <verb> $ git <verb> --help $ man git-<verb> #比如 $ git help config
1. 你就能初始化一个新的代码仓库, 2. 做一些适当的配置; 3. 开始或停止跟踪某些文件; 4. 暂存或提交某些更新。我们还会展示如何让 Git 忽略某些文件,或是名称符合特定模式的文件; 5. 如何既快且容易地撤消犯下的小错误; 6. 如何浏览项目的更新历史,查看某两次更新之间的差异; 7.如何从远程仓库拉数据下来或者推数据上去。2.1 取得项目的 Git 仓库 2.1.1 从当前目录初始化
$ git init
在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。
不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录,但我们还没有开始跟踪管理项目中的任何一个文件。
如果当前目录下有几个文件想要纳入版本控制,需要先用 git add 命令告诉 Git 开始对这些文件进行跟踪,然后提交:
$ git add *.c $ git add README $ git commit -m 'initial project version'2.1.2 从现有仓库克隆
$ git clone git://github.com/schacon/grit.gitclone 而不是 checkout。这是个非常重要的差别,Git 收取的是项目历史的所有数据(每一个文件的每一个版本),服务器上有的数据克隆之后本地也都有了。实际上,即
$ git status
$ git add README2.2.3 暂存已修改文件 运行 git add 命令(这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件, 或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等) 2.2.4 忽略某些文件
文件 .gitignore 的格式规范如下: • 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。 • 可以使用标准的 glob 模式匹配。 • 匹配模式最后跟反斜杠(/)说明要忽略的是目录。 • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a, 要么匹配一个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配 (比如 [0-9] 表示匹配所有 0 到9 的数字)。
# 此为注释 – 将被 Git 忽略 *.a # 忽略所有 .a 结尾的文件 !lib.a # 但 lib.a 除外 /TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO build/ # 忽略 build/ 目录下的所有文件 doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt2.2.5 查看已暂存和未暂存的更新 要查看尚未暂存的文件更新了哪些部分,不加参数直接输入 :
$ git diff
若要看已经暂存起来的文件和上次提交时的快照之间的差异,可以用
$ git diff --cached
命令。(Git 1.6.1 及更高版本还允许使用 git diff --staged
单单 git diff 不过是显示还没有暂存起来的改动,而不是这次工作和上次提交之间的差异。
所以有时候你一下子暂存了所有更新过的文件后,运行 git diff 后却什么也没有,就是这个原因。
2.2.6 提交更新
$ git commit这种方式会启动文本编辑器以便输入本次提交的说明。(默认会启用 shell 的环境变量$EDITOR 所指定的软件,一般都是 vim 或 emacs。当然也可以按照第一章介绍的方式, 使用 git config --global core.editor 命令设定你喜欢的编辑软件。) 也可以使用 -m 参数后跟提交说明的方式,在一行命令中提交更新:
$ git commit -m "Story 182: Fix benchmarks for speed"2.2.7 跳过使用暂存区域 尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 git commit 加上 -a 选项,Git就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add 步骤
$ git commit -a -m 'added new benchmarks'2.2.8 移除文件
$ git rm grit.gemspec最后提交的时候,该文件就不再纳入版本管理了。如果删除之前修改过并且已经放到暂存区域的话, 则必须要用强制删除选项 -f(译注:即 force 的首字母),以防误删除文件后丢失修改的内容。 另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,仅是从跟踪清单中删除。比如一些大型日志文件或者一堆 .a 编译文件,不小心纳入仓库后,要移除跟踪但不删除文件, 以便稍后在 .gitignore文件中补上,用 --cached 选项即可:
$ git rm --cached readme.txt
2.2.9 移动文件
$ git mv file_from file_to
其实,运行 git mv 就相当于运行了下面三条命令:
$ mv README.txt README $ git rm README.txt $ git add README2.3 查看提交历史 在提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,可以使用 git log命令。 每次更新都有一个 SHA-1 校验和、作者的名字和电子邮件地址、提交时间,最后缩进一个段落显示提交说明。
$ git log --pretty=oneline $ git log --pretty=format:"%h - %an, %ar : %s"
选项 说明 %H 提交对象(commit)的完整哈希字串 %h 提交对象的简短哈希字串 %T 树对象(tree)的完整哈希字串 %t 树对象的简短哈希字串 %P 父对象(parent)的完整哈希字串 %p 父对象的简短哈希字串 %an 作者(author)的名字 %ae 作者的电子邮件地址 %ad 作者修订日期(可以用 -date= 选项定制格式) %ar 作者修订日期,按多久以前的方式显示 %cn 提交者(committer)的名字 %ce 提交者的电子邮件地址 %cd 提交日期 %cr 提交日期,按多久以前的方式显示 %s 提交说明一些其他常用的选项及其释义
选项 说明 -p 按补丁格式显示每个更新之间的差异。 --stat 显示每次更新的文件修改统计信息。 --shortstat 只显示 --stat 中最后的行数修改添加移除统计。 --name-only 仅在提交信息后显示已修改的文件清单。 --name-status 显示新增、修改、删除的文件清单。 --abbrev-commit 仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。 --relative-date 使用较短的相对时间显示(比如,“2 weeks ago”)。 --graph 显示 ASCII 图形表示的分支合并历史。 --pretty 使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。2.4 撤消操作 2.4.1 修改最后一次提交 有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交:
$ git commit --amend此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,而所提交的文件快照和之前的一样。
$ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend上面的三条命令最终得到一个提交,第二个提交命令修正了第一个的提交内容。 2.4.2 取消已经暂存的文件
$ git reset HEAD benchmarks.rb把提交到暂存的文件又撤回到本地 2.4.3 取消对文件的修改
$ git checkout -- benchmarks.rb2.5 远程仓库的使用 2.5.1 查看当前的远程库 要查看当前配置有哪些远程仓库,可以用 git remote 命令,它会列出每个远程库的简短名字。在克隆完某个项目后,至少可以看到一个名为 origin 的远程库, Git 默认使用这个名字来标识你所克隆的原始仓库:
$ git remote也可以加上 -v 选项(译注:此为 —verbose 的简写,取首字母),显示对应的克隆地址:
$ git remote -v bakkdoor git://github.com/bakkdoor/grit.git cho45 git://github.com/cho45/grit.git defunkt git://github.com/defunkt/grit.git koke git://github.com/koke/grit.git origin git@github.com:mojombo/grit.git这样一来,我就可以非常轻松地从这些用户的仓库中,拉取他们的提交到本地。请注意,
$ git remote origin $ git remote add pb git://github.com/paulboone/ticgit.git $ git remote -v origin git://github.com/schacon/ticgit.git pb git://github.com/paulboone/ticgit.git
现在可以用字串 pb 指代对应的仓库地址了。比如说,要抓取所有 Paul 有的,但本地仓库没有的信息,可以运行 git fetch pb:
$ git fetch pb remote: Counting objects: 58, done. remote: Compressing objects: 100% (41/41), done. remote: Total 44 (delta 24), reused 1 (delta 0) Unpacking objects: 100% (44/44), done. From git://github.com/paulboone/ticgit * [new branch] master -> pb/master * [new branch] ticgit -> pb/ticgit现在,Paul 的主干分支(master)已经完全可以在本地访问了,对应的名字是 pb/master,你可以将它合并到自己的某个分支,或者切换到这个分支,看看有些什么有趣的更新。 2.5.3 从远程仓库抓取数据
$ git fetch [remote-name]此命令会到远程仓库中拉取所有你本地仓库中还没有的数据。运行完成后,你就可以在本地访问该远程仓库中的所有分支,将其中某个分支合并到本地,或者只是取出某个分支,一探究竟。 如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以,git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。 有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。 可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支 实际上,默认情况下 git clone 命令本质上就是 自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有
$ git push [remote-name] [branch-name]如果要把本地的 master 分支推送到 origin 服务器上(再次说明下,克隆操作会自动使用默认的 master 和 origin 名字)
$ git push origin master2.5.5 查看远程仓库信息
git remote show [remote-name] 查看某个远程仓库的详细信息
$ git remote show origin
2.5.6 远程仓库的删除和重命名
$ git remote rename pb paul对远程仓库的重命名,也会使对应的分支名称发生变化,原来的 pb/master 分支现在成了 paul/master 碰到远端仓库服务器迁移,或者原来的克隆镜像不再使用,又或者某个参与者不再贡献代码,那么需要移除对应的远端仓库,可以运行 git remote rm 命令:
$ git remote rm paul2.6 打标签 Git 也可以对某一时间点上的版本打上标签。人们在发布某个软件版本(比如 v1.0 等等)的时候,经常这么做。本节我们一起来学习如何列出所有可用的标签,如何新建标签,以及各种不同类型标签之间的差别。 2.6.1 列显已有的标签
$ git tag v0.1 v1.3 $ git tag -l 'v1.4.2.*' v1.4.2.1 v1.4.2.2 v1.4.2.3 v1.4.2.42.6.2 新建标签 Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。 而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来
$ git tag -a v1.4 -m 'my version 1.4'可以使用 git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象。
$ git show v1.4
2.6.4 签署标签
如果你有自己的私钥,还可以用 GPG 来签署标签,只需要把之前的 -a 改为 -s (译注:取 Signed 的首字母)即可:
$ git tag -s v1.5 -m 'my signed 1.5 tag'2.6.5 轻量级标签 轻量级标签实际上就是一个保存着对应提交对象的校验和信息的文件。要创建这样的标签,一个 -a,-s 或 -m 选项都不用,直接给出标签名字即可:
$ git tag v1.4-lw $ git show v1.4-lw2.6.6 验证标签 可以使用 git tag -v [tag-name] (译注:取 verify 的首字母)的方式验证已经签署的标签。此命令会调用 GPG 来验证签名,所以你需要有签署者的公钥,存放在 keyring 中,才能验证: 2.6.8 分享标签 默认情况下,git push 并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname] 即可:
$ git push origin v1.5
如果要一次推送所有(本地新增的)标签上去,可以使用 --tags 选项:
$ git push origin --tags
2.7 技巧和窍门
2.7.1 自动完成
如果你用的是 Bash shell,可以试试看 Git 提供的自动完成脚本。下载 Git 的源代码,进入 contrib/completion 目录,会看到一个 git-completion.bash 文件。将此source ~/.git-completion.bash
$ git config --global alias.co checkout $ git config --global alias.br branch $ git config --global alias.ci commit $ git config --global alias.st status使用这种技术还可以创造出新的命令,比方说取消暂存文件时的输入比较繁琐,可以自己
$ git config --global alias.unstage 'reset HEAD --'
这样一来,下面的两条命令完全等同:
$ git unstage fileA
$ git reset HEAD fileA
如果你觉得上面的东西太多,一下很难接受:那么其实你只想掌握git的基本操作:只要10分钟就可以: http://rogerdudler.github.io/git-guide/index.zh.html
下次再看:第三章 Git分支
哈哈:网上居然有个乐队叫Git Fresh... 每次看Dota搞笑视频时放的就是他们的歌:Booty Music..就是那个一直循环说Let's do it do it ,That‘s the way you like it 的歌,把git和这联系起来,那感觉好好笑。。。。
别装逼,我也会.....哈哈哈哈。。。。