分布式版本控制系统 Git 客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。因为每一次的提取操作,实际上都是一次对代码仓库的完整备份。
状态 | 描述 |
---|---|
已提交 | 该文件以及被安全的保存在本地数据库中了。 |
已修改 | 修改了某个文件,但还没有提交保存。 |
已暂存 | 把已修改的文件放在下次提交时要保存的清单中。 |
$ git config --global user.name zhangwuliang
$ git config --global user.email zhangwuliang@example.com
$ git config --global core.editor emacs
$ git config --global merge.tool vimdiff
$ git config --global diff.tool vimdiff
$ git config --global difftool.prompt false
$ git config --global alias.d difftool
$git diff
$ git config --list
$ git config user.name
$ git help <verb>
$ git <verb> --help
$ man git-<verb>
$ git init
$ git add *.c
$ git add README
$ git commit -m 'initial project version'
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,像是日志或者编译过程中创建的等等。我们可以创建一个名为 .gitignore 的文件,列出要忽略的
文件模式。
$ cat .gitignore
*.[oa] #忽略所有以 .o 或 .a 结尾的文件
*~ #忽略所有以波浪符( ~)结尾的文件
所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
可以使用标准的 glob 模式匹配。
匹配模式最后跟反斜杠( /)说明要忽略的是目录。
要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号( !)取回。
此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件 !lib.a # 但 lib.a 除外 /TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO build/ # 忽略 build/ 目录下的所有文件 doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
查看尚未暂存的文件修改:
$ git diff #查看尚未暂存的文件修改了哪些部分
$ git checkout filename #放弃尚未暂存的修改
查看已暂存的文件和上次提交的差异:
$ git diff --cached
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。可以用 git rm 命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 “Changed but not updated” 部分(也就是_未暂存_清单)看到。如果删除之前修改过并且已经放到暂存区的话,则必须使用强制删除选项 -f。
另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。换句话说,仅是从跟踪清单中删除。比如一些大型日志文件或者一堆 .a 编译文件,不小心纳入仓库后,要移除跟踪但不删除文件,以便稍后在 .gitignore 文件中补上,用 --cached 选项即可。
git rm 1.txt git rm -f 1.txt git rm --cached 1.txt
也可使用 glob 模式:
git rm log/\*.log
git rm \*.swap
#通配符必须使用\,
git mv file_from file_to
有时候我们提交完了才发现漏掉了几个文件没有加,或者提交信息写错了。想要撤消刚才的提交操作,可以使用 --amend 选项重新提交:
$ git commit --amend
此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,而所提交的文件快照和之前的一样。
启动文本编辑器后,会看到上次提交时的说明,编辑它确认没问题后保存退出,就会使用新的提交说明覆盖刚才失误的提交。
如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交。
$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend
上面的三条命令最终得到一个提交,第二个提交命令修正了第一个的提交内容。
git reset filename
git checkout -- filename
git remote git remote -v #显示对应的远程地址
git remote add [shortname] [url] git remote add pb git://github.com/zhangwuliang/xx.git #现在pb就代表对应仓库的地址了
git fetch [remote-name]
此命令会到远程仓库中拉取所有你本地仓库中还没有的数据。运行完成后,你就可以在本地访问该远程仓库中的所有分支,将其中某个分支合并到本地,或者只是取出某个分支,一探究竟。
如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以, git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。
有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。
如果设置了某个分支用于跟踪某个远端仓库的分支,可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。在日常工作中我们经常这么用,既快且好。
实际上,默认情况下 git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。所以一般我们运行 git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中当前分支。
git push [remote-name] [branch-name]
git remote show [remote-name]
git remote rename pb paul #把pb改成paul git remote rm paul #删除远程仓库paul
git tag git tag -l 'v1.4.2.*' #列出符合条件的标签
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。
而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。
一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
git tag -a v1.4 -m 'my version 1.4' #新建含附注的标签 git show v1.4 #显示标签详细信息 git tag v1.4-lw #轻量级标签 git tag -a v1.2 9fceb02 #针对某次提交打标签
默认情况下, git push 并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。
git push origin v1.5 git push origin --tags #一次推送所有(本地新增的)标签上去
$ 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 --'