有错误和改进的地方望留言,谢谢 : )
顺便推荐一下,git入门教程
全局设置
git config --system
// 对应的是 /etc/gitconfig
文件。git config --global
// 对应的是 ~/.gitconfig
文件。
git config --global user.name 'Your name'
// 设置git的用户名git config --global user.email 'youremail@email.com'
// 设置Email地址git config --global core.editor vim
// 默认编辑器修改为 Vim
git config --global alias.别名 '原命令'
// 为命令取别名git config --global alias.st status
// 把status => stgit config --global alias.co checkout
// checkout => cogit config --global alias.ci commit
// commit => cigit config --global alias.br branch
// branch => brgit config --global alias.unstage reset HEAD
// reset HEAD => unstagegit config --global alias.last log -1
// 显示最后一次提交信息git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
// 让git
显示日志时,不同区域显示不同的颜色。git config --global color.ui true
// 让git显示颜色。config
是命令 --global
是 config
的参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。
.gitignore
// 在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。
所有空行或者以注释符号
#
开头的行都会被Git
忽略。可以使用标准的
glob
模式匹配。匹配模式最后跟反斜杠(
/
)说明要忽略的是目录。要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
glob
模式是指shell
所使用的简化了的正则表达式。星号(*
)匹配零个或多个任意字符;[abc]
匹配任何一个列在方括号中的字符(这个例子要么匹配一个a
,要么匹配一个b
,要么匹配一个c
);问号(?
)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如[0-9]
表示匹配所有0
到9
的数字)。
cat .git/config
// 查看 git
的配置文件,如果要删除某个全局设置,直接删除对应的行即可。
帮助
git help
// 查看 git 命令的所有参数,和 git 下的所有命令git help commit
// 可以查看commit命令的所有参数,和其他详细信息,此命令相当好用 。git <verb> --help
// 查看某个命令信息man git-<verb>
// 查看某个命令信息
仓库
git init
// 初始化一个有工作区域的仓库,工作目录下面的所有文件都不外乎这两种状态:已跟踪或未跟踪。git init --bran git.git
// 初始化一个不带工作区的仓库
初始化时git会自动初始化一个 master
主分支,并且在当前目录下会出现一个名为 .git
的目录,所有 Git 需要的数据和资源都存放在这个目录中。
所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。git remote
// 它会列出每个远程库的简短名字。git remote add [shortname] [url]
// 添加远程仓库。git remote -v
// 此为 --verbose
的简写,会列出 shortname url 权限。git remote show [remote-name]
// 查看某个远程仓库的详细信息。git remote rename [old-name] [new-name]
// 修改某个远程仓库在本地的简称。git remote rm [repertory-name]
// 移除某个远端仓库。
克隆
git clone [url]
// 克隆某个仓库,初次克隆某个仓库时,工作目录中的所有文件都属于已跟踪文件,且状态为未修改,会自动将远程仓库归于 origin
名下,并自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有 master 分支)。git clone git://github.com/schacon/grit.git
// 在当前目录下创建一个名为grit的目录,其中包含一个 .git
的目录,用于保存下载下来的所有版本记录,然后从中取出最新版本的文件拷贝。git clone git://github.com/schacon/grit.git mygrit
// 自己定义要新建的项目目录名称,可以在上面的命令末尾指定新的名字,这里是 mygrid
。
添加
git add <file>
// 添加一个文件添加到暂存区,可反复多次使用,添加多个文件 如: git add text.txt text2.txt
,其实 git add
的潜台词就是把目标文件快照放入暂存区域,也就是 add file into staged area
,同时未曾跟踪过的文件标记为需要跟踪。git add <dirname>
// 添加目录下所有文件到暂存区。git add --all
// 把所有修改的文件添加到暂存区。git add .
// 把所有修改的文件添加到暂存区。git stage
// 跟 add
作用相同。
提交
git commit
// 不带 -m
的提交会启动文本编辑器以便输入本次提交的说明,(默认会启用 shell 的环境变量 $EDITOR 所指定的软件,一般都是 vim 或 emacs。当然也可以按照第一章介绍的方式,使用 git config --global core.editor 命令设定你喜欢的编辑软件。),如果启用的是vim,打开后光标所在行就是输入行,按 i
进入输入模式(在光标所在行插入内容),输入内容不用带单引或双引,按 Esc
退出输入模式,按 Shift + :
进入命令模式,输入 wq
保存并退出。
git commit -m 'add a file'
// 把暂存区里的东西提交到当前分支,-m
参数后面输入的是本次提交的说明。git commit -a -m 'some message'
// 加上 -a
选项,Git
就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤。git commit --amend
// 此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命令的话,相当于有机会重新编辑提交说明,但将要提交的文件快照和之前的一样。
git commit -m 'initial commit'
git add forgotten_file
git commit --amend
上面的三条命令最终只是产生一个提交,第二个提交命令修正了第一个的提交内容,如果给 commit
加上 -m
参数,那么会覆盖以前的说明,不加会弹出编辑器,可以修改说明。
推送
git push [remote-name] [branch-name]
git push origin master
// 把master分支当前版本推送到远程仓库对应的分支上。
拉取
git fetch orgin
// 将远端的数据拉到本地仓库,并不自动合并到当前工作分支。git pull
// 抓取远程仓库所有分支更新并合并到本地。git pull origin master
// 更新远程分支 master
合并到本地 master
分支。
查看
git status
// 可以让我们时刻掌握仓库当前的状态。git diff <file>
// 查看具体的修改,显示的格式正是Unix通用的diff格式,此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容(不加文件名显示的是全部文件)。git diff --staged
// 此命令比较的是已经暂存起来的文件和上次提交时的快照之间的差异,该命令是1.6.1以后出现的,以前的版本用 git diff --cached
,功能是一样的。git log
// 显示提交日志,从最近到最远。git log -- <path>
// 某个目录下的日志,放在所有参数之后用 --
隔开路径。git log -p -2
// -p
选项展开显示每次提交的内容差异,用 -2
则仅显示最近的两次更新。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
提交说明
git log --graph --pretty=oneline
// 多出一些 ASCII
字符串表示的简单图形,形象地展示了每个提交所在的分支及其分化衍合情况。
下面列出了 git log
一些其他常用的选项及其释义。
-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(后跟指定格式)。-(n)
仅显示最近的 n 条提交。--since
,--after
仅显示指定时间之后的提交,时间格式2.weeks
,2015-01-01
,2 years 1 day 3 minutes ago
等。--until
,--before
仅显示指定时间之前的提交。--author
仅显示指定作者相关的提交。--committer
仅显示指定提交者相关的提交。--grep
搜索提交说明中的关键字,得到同时满足这两个选项搜索条件的提交,就必须用--all-match
选项。否则,满足任意一个条件的提交都会被匹配出来。
git reflog
// 可以查看所有分支的所有操作记录(包括commit和reset的操作),包括已经被删除的commit记录,git log则不能察看已经删除了的commit记录。git config --list
// 检查已有的配置信息,有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。git config user.name
// 可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可。
重置
git reset --hard HEAD^
// 回退到上一个版本,^^
就是退回上两个版本,HEAD
指向的版本是当前版本。git reset --hard HEAD~100
// 退回到上100个版本。git reset --hard 112312
// 回到指定的版本112312,版本号不用写全,只要能唯一确定是哪个版本就行了。git checkout -- <file>
// 重置选着的文件, 在工作区的修改,从上一个已提交的版本中更新回来,未提交的内容全部会回滚。git checkout -- .
// 重置工作区所有文件的所有修改,从上一个已提交的版本中更新回来,未提交的内容全部会回滚。git reset HEAD <file>
// 把暂存区的修改撤销掉,重新放回工作区,git reset
命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD
时,表示最新的版本。git revert HEAD^
// 恢复到现有的提交,并产生新提交,和reset
不同的是,revert
是会产生新的提交记录,而 reset
是把 HEAD
指向了以前的一个版本,并不会产生新提交。
分支
git branch
// 查看分支,会列出所有分支,当前分支前面会标一个 *
号。git branch dev
// 创建名叫 dev
的分支。git checkout dev
// 切换到 dev
分支上。git checkout -b dev
// 创建+切换分支。git checkout -b dev origin/dev
// 作用是 checkout
远程的dev分支,在本地起名为 dev
分支,并切换到本地的 dev
分支git merge dev
// 合并分支,把 dev
分支合并到当前分支,快速合并模式 Fast forward
,“快速模式”,也就是直接把master指向dev的当前提交,如果两个分支的文件都有改动是不能快速合并的。git merge --no-ff -m '合并分支' dev
// 把 dev
合并到当前分支,不用快速合并。git branch --set-upstream-to=origin/master master
// 作用是使你的本地master分支与远程的origin/master分支关联,关联目的是如果在本地分支下操作: git pull, git push ,不需要指定在命令行指定远程的分支。git rebase
// 移动分支。git branch -d dev
// 删除分支。git branch -D feature-vulcan
// 强行删除没有被合并过的 feature-vulcan 分支。git branch -a
查看远程分支,远程分支会用红色表示出来(如果你开了颜色支持的话)
在Git v1.7.0 之后,可以使用这种语法删除远程分支:
git push origin --delete <branchName>
// 删除远程分支
git push origin :<branchName>
// 否则,可以使用这种语法,推送一个空分支到远程分支,其实就相当于删除远程分支
标签
Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
git tag
// 查看所有标签信息,标签是按字母排序的,不是按创建时间。git tag v1.0
// 在当前分支上创建一个 轻量级标签
v1.0
标签,默认是打在最新提交的commit上的。git tag v1.0 commit_id
// 在当前分支上的commit_id上打一个标签 v1.0
,那么以后你想查看该版本时,就可以使用 v1.0
标签名,而不是哈希值了。git tag -a <tagname> -m <message> <branchName>
// 创建带有附注的标签,用 -a
指定标签名,-m
指定附注文字 <branchName> 指明把标签打在那个分支上。git show <tagname>
// 查看标签信息。git -d <tagname>
// 删除标签。git push origin <tagname>
// 推送某个标签到远程。git push origin --tags
// 推送所有未推送的标签到远程。git push origin :refs/tags/<tagname>
// 删除某个远程的标签,要删除远程标签,必须要先删除本地。
在Git v1.7.0 之后,可以使用这种语法删除远程Tag
git push origin --delete tag <tagname>
删除远程tag
git tag -d <tagname>
// 这是删除tag的方法,推送一个空tag到远程tag:git push origin :refs/tags/<tagname>
储藏
git stash
// git 把当前分支的工作区储藏起来,切换到其他分支不会影响储藏的分支。git stash list
// 查看储藏的工作区。git stash apply
// 恢复储藏的工作区。git stash drop
// 删除储藏工作区。git stash pop
// 恢复+删除储藏工作区。
其他
git mv file_from file_to
// mv
是移动文件,此处作用相当于改名。把 file_from
改为 file_to
。git rm <filename>
// 从当前的工作空间中和索引中删除文件。git rm --cached <filename>
// 把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。git rm log/\*.log
// 注意到星号 *
之前的反斜杠 \
,因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell
来帮忙展开(译注:实际上不加反斜杠也可以运行,只不过按照 shell
扩展的话,仅仅删除指定目录下的文件而不会递归匹配。上面的例子本来就指定了目录,所以效果等同,但下面的例子就会用递归方式匹配,所以必须加反斜杠。)。此命令删除所有 log/
目录下扩展名为 .log
的文件。git rm \*~
// 会递归删除当前目录及其子目录中所有 ~ 结尾的文件。