目录
一、git简介
二、git基本命令
创建和克隆仓库
记录更新到仓库
查看提交历史
撤销操作
远程仓库的使用
打标签
三、git分支
git是一种分布式版本控制系统(Distributed Version Control System,简称 DVCS)。git 对待数据的方法是直接记录快照,而非差异比较。git 数据库中保存的信息都是以文件内容的哈希值来索引,而不是文件名。每次提交更新时,git主要对当时的全部文件制作一个快照并保存这个快照的索引。如果文件没有修改,git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。
git 有三种状态,你的文件可能处于其中之一:已提交(committed)、已修改(modified)和已暂存(staged)。 已提交表示数据已经安全的保存在本地数据库中。 已修改表示修改了文件,但还没保存到数据库中。 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。
由此引入 git 项目的三个工作区域的概念:git 仓库、工作目录以及暂存区域。git 仓库目录是 git 用来保存项目的元数据和对象数据库的地方。工作目录是对项目的某个版本独立提取出来的内容。暂存区域是一个文件,保存了下次将提交的文件列表信息,一般在 git 仓库目录中,有时候也被称作‘索引’。
基本的 git 工作流程如下:
在工作目录中修改文件。
暂存文件,将文件的快照放入暂存区域。
提交更新,找到暂存区域的文件,将快照永久性存储到 git 仓库目录。
在使用git之前,需要设置自己的用户名称和邮箱:
git config --global user.name "zhangsan"
git config --global user.email [email protected]
配置git默认的文本编辑器:
git config --global core.editor gedit
设置完成后,可以使用git config --list命令来查看你的配置。
配置git命令的别名,使用 git config –global alias 命令来配置,比如 我想用 st 代表 status
git config --global alias.st status
git当中有很多操作命令,如果不知道某个命令如何使用可以利用help获取帮助,有三种方法可以找到 git 命令的使用手册:
1、git help 命令
2、git 命令 --help
3、man git-命令
在本地的当前项目中初始化仓库(即创建一个仓库)
进入项目目录中,然后输入:
git init
该命令将创建一个名为 .git
的子目录,这个子目录含有你初始化的 git 仓库中所有的必须文件。但是,在这个时候,我们仅仅是做了一个初始化的操作,项目里的文件还没有被跟踪。我们可以通过[ git add
文件名 ] 命令来实现对指定文件的跟踪,然后执行 git commit
提交。
克隆github上现有的仓库
克隆仓库的命令格式是 git clone [url]
。例如:
git clone https://github.com/528405176/hello-world
你可以在克隆远程仓库的时候,自定义本地仓库的名字,使用如下命令:
git clone https://github.com/528405176/hello-world myrepository
检查当前文件状态
git status
git status
命令的输出十分详细,但其用语有些繁琐。 如果你使用 git status -s
命令或 git status --short
命令,将得到一种更为紧凑的格式输出。新添加的未跟踪文件前面有 ??
标记,新添加到暂存区中的文件前面有 A
标记,修改过的文件前面有 M
标记。M
有两个可以出现的位置,出现在右边的 M
表示该文件被修改了但是还没放入暂存区,出现在靠左边的 M
表示该文件被修改了并放入了暂存区。
创建一个新的文件
echo 'My Project' > newfile
此时再次使用git status命令能够看到一个未跟踪文件,git 不会自动将我们新创建的文件纳入跟踪范围,需要我们使用git add命令将其纳入跟踪范围
git add newfile
此时再运行 git status
命令,会看到 newfile 文件已被跟踪,并处于暂存状态。
如果我们修改一个项目中的文件,修改后的文档会处于非暂存状态,我们可以使用git add的另一个功能,将非暂存状态的文件加入暂存区域。否则我们提交的时候将不会提交修改后的文档。
查看已暂存和未暂存的修改内容
查看尚未暂存的文件更新了哪些部分,具体修改了什么地方,可以用 git diff
命令:
git diff
此命令比较的是工作目录中当前文件和暂存区域快照之间的差异,如果要查看已暂存的将要添加到下次提交里的内容,可以用:
git diff --staged
或者
git diff --cached
提交更新
git commit
这种方式会启动文本编辑器以便输入本次提交的说明。默认的提交消息包含最后一次运行 git status
的输出,放在注释行里,另外开头还有一空行,供输入提交说明。如果想要提交更详细的修改内容的说明,可以用 -v
选项,这会将你所做的改变的 diff 输出放到编辑器中。
另外,你也可以在 commit
命令后添加 -m
选项,将提交说明与命令放在同一行:
git commit -m "added a new file named newfile"
跳过使用暂存区域直接强制提交更新
git commit -a
使用上述命令,git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤。
移除文件
如果只是手动或者在命令行使用rm从工作目录中删除文件,运行git status会发现该文件出现在未暂存清单。要从 git 中彻底移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。
git rm newfile
git commit -m "delete newfile"
如果删除之前修改过并且已经放到暂存区域的话,但是又并没有提交,则必须要用强制删除选项 -f
git rm -f newfile
另一种情况,如果我们想把文件从 git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。换句话说,想让文件保留在磁盘,但是并不想让 git 继续跟踪。这时可以使用--cached选项:
git rm --cached newfile
git rm
命令后面可以列出文件或者目录的名字,也可以使用glob模式。(所谓的 glob 模式是指 shell 所使用的简化了的正则表达式,也被称之为 shell 通配符)比如:
git rm log/\*.log
注意星号 *
之前的反斜杠 \
, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除 log/
目录下扩展名为 .log
的所有文件。
移动文件(事实上常用来重命名)
git mv oldname newname
默认不用任何参数的话,git log
会按提交时间列出所有的更新,最近的更新排在最上面。这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。
git log
也可以使用一些选项过滤提交信息,-p
用来显示每次提交的内容差异,可以加上 -2
来仅显示最近两次提交
git log -p -2
如果你想看到每次提交的简略的统计信息,你可以使用 --stat
选项,--stat
选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结。
git log --stat
--pretty
这个选项可以指定使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如用 oneline
将每个提交放在一行显示,查看的提交数很大时非常有用。 另外还有 short
,full
和 fuller。
git log --pretty=oneline
还可以利用format选项定制显示的格式,git log --pretty=format
常用的选项
选项 | 说明 |
---|---|
|
提交对象(commit)的完整哈希字串 |
|
提交对象的简短哈希字串 |
|
树对象(tree)的完整哈希字串 |
|
树对象的简短哈希字串 |
|
父对象(parent)的完整哈希字串 |
|
父对象的简短哈希字串 |
|
作者(author)的名字 |
|
作者的电子邮件地址 |
|
作者修订日期(可以用 --date= 选项定制格式) |
|
作者修订日期,按多久以前的方式显示 |
|
提交者(committer)的名字 |
|
提交者的电子邮件地址 |
|
提交日期 |
|
提交日期,按多久以前的方式显示 |
|
提交说明 |
eg:
git log --pretty=format:"%h - %an, %ar : %s"
oneline和format还可以与--graph结合使用,显示 ASCII 图形表示的分支合并历史。
git log --pretty=format:"%h %s" --graph
git log
的常用选项
选项 | 说明 |
---|---|
|
按补丁格式显示每个更新之间的差异。 |
|
显示每次更新的文件修改统计信息。 |
|
只显示 --stat 中最后的行数修改添加移除统计。 |
|
仅在提交信息后显示已修改的文件清单。 |
|
显示新增、修改、删除的文件清单。 |
|
仅显示 SHA-1 的前几个字符,而非所有的 40 个字符。 |
|
使用较短的相对时间显示(比如,“2 weeks ago”)。 |
|
显示 ASCII 图形表示的分支合并历史。 |
|
使用其他格式显示历史提交信息。可用的选项包括 oneline,short,full,fuller 和 format(后跟指定格式)。 |
限制输出长度
git log
还有许多非常实用的限制输出长度的选项,也就是只输出部分提交信息。
选项 | 说明 |
---|---|
|
仅显示最近的 n 条提交 |
|
仅显示指定时间之后的提交。 |
|
仅显示指定时间之前的提交。 |
|
仅显示指定作者相关的提交。 |
|
仅显示指定提交者相关的提交。 |
|
仅显示含指定关键字的提交 |
|
仅显示添加或移除了某个关键字的提交 |
eg:列出所有最近两周内的提交
git log --since=2.weeks
还可以给出若干搜索条件,列出符合的提交。注意,如果要得到同时满足这两个选项搜索条件的提交,就必须用 --all-match
选项。否则,满足任意一个条件的提交都会被匹配出来。
重新提交前一次的提交,换句话说,如果你的前一次提交有任何遗漏(少提交了几个文件,文件内内容有误,提交说明写错了等),你可以随时进行弥补或者更正,然后重新提交。这样会覆盖前一次提交的记录,但前一次的提交时间会保留。重新提交时,提交信息编辑器中可以看到上次的提交说明,可以编辑覆盖。
git commit --amend
取消暂存的文件git reset HEAD
git reset HEAD newfile
撤销对文件的修改git checkout --
git checkout -- newfile
查看远程仓库
git remote
可以指定选项 -v
,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
git remote -v
如果是你和其他人合作的项目,那么远程仓库除了源仓库origin(这是 git 给你克隆的仓库服务器的默认名字),还会列出所有协作者的仓库。这样我们可以轻松拉取其中任何一个用户的贡献。
添加远程仓库
运行git remote add
添加一个新的远程 Git 仓库,同时指定一个简写(shortname为url的简写,作为远程仓库的名字)。
git remote add username2 https://github.com/username2/hello-world
从远程仓库中抓取与拉取
git fetch 远程仓库名
这个命令会访问远程仓库,从中拉取所有你没有的数据。执行完成后,你将会拥有那个远程仓库中所有分支的引用,但并不会自动合并或修改你当前的工作,你必须手动将其合并入你的工作。
git fetch username2
默认情况下,git clone
命令会自动设置本地 master 分支跟踪克隆的远程仓库的 master 分支(或不管是什么名字的主分支)。但不会涉及其他工作分支的内容。
推送到远程仓库
git push 远程仓库名 分支名
eg:当你想要将 master 分支推送到 origin
服务器时
git push origin master
只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先将他们的工作拉取下来并将其合并进你的工作后才能推送。
查看某一个远程仓库的更多信息
git remote show origin
远程仓库的移除与重命名
移除
git remote rm username2
重命名
git remote rename username2 newname
git 可以给历史中的某一个提交打上标签,以示重要
列出标签
git tag
也可以使用特定的模式查找标签。
git tag -l 'v1.8.5*'
创建标签
git 使用两种主要类型的标签:轻量标签(lightweight)与附注标签(annotated)。
一个轻量标签很像一个不会改变的分支 - 它只是一个特定提交的引用。轻量标签本质上是将提交校验和存储到一个文件中 - 没有保存任何其他信息。
然而,附注标签是存储在 Git 数据库中的一个完整对象。 它们是可以被校验的;其中包含打标签者的名字、电子邮件地址、日期时间;还有一个标签信息;并且可以使用 GNU Privacy Guard (GPG)签名与验证。 通常建议创建附注标签。
附注标签(运行 tag
命令时指定 -a
选项)
git tag -a v1.4 -m 'my version 1.4'
这句命令为最后一次的提交打上版本标签。使用 git show
命令可以看到标签信息与对应的提交信息。
git show v1.4
轻量标签(运行tag命令时不指定任何选项)
git tag v1.4-lw
这时,如果在标签上运行 git show
,你不会看到额外的标签信息, 命令只会显示出提交信息。
我们可以为一个提交打上多个附注标签和轻量标签,但是系统不允许出现同名标签。(事实上多个标签也没什么用)
为历史提交打标签
要给指定的历史提交打标签,需要在命令的末尾指定那个历史提交的校验和(或部分校验和)。
git tag -a v0.6 db89a9695 -m "my version v0.6"
共享标签
默认情况下,git push
命令并不会传送标签到远程仓库服务器上。 在创建完标签后你必须显式地推送标签到共享服务器上。
git push origin v1.1
如果想要一次性推送很多标签,也可以使用带有 --tags
选项的 git push
命令。 这将会把所有不在远程仓库服务器上的标签全部传送到那里。
git push origin --tags
现在,当其他人从仓库中克隆或拉取,他们也能得到你的那些标签。
我们知道项目当中保存的文件是通过一次次的提交推送累积的。每次提交会创建一个提交对象,该提交对象中包含一个指向暂存内容快照的指针,以及指向父对象的指针。首次提交产生的提交对象没有父对象,之后每次提交产生的提交对象都会把前一个提交对象当做父对象,而由多个分支合并产生的提交对象有多个父对象。
Git 的分支,其实本质上仅仅是指向提交对象的可变指针。 Git 的默认分支(主分支)名字是 master
。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master
分支。 它会在每次的提交操作中自动向前移动。
分支创建
git branch testing
git只是为你在当前所在的提交对象上创建了一个可以移动的新的指针,git branch
命令仅仅 创建 一个新分支,并不会自动切换到新分支中去。
分支切换
git有一个名为 HEAD
的特殊指针,指向当前所在的本地分支(项目默认初始分支为master,所以HEAD一开始是指向master分支的)。
可以使用 git log
命令查看各个分支当前所指的对象。 提供这一功能的参数是 --decorate
。
git log --oneline --decorate
要切换到一个已存在的分支,需要使用 git checkout
命令。
git checkout testing
这样 HEAD
就指向 testing
分支了。
我们也可以利用checkout新建分支的同时切换到该分支
git checkout -b testing2
通过HEAD指针切换不同的分支工作,项目就会产生分叉。
我们可以使用 git log
命令查看分叉历史。 运行 git log --oneline --decorate --graph --all
,它会输出你的提交历史、各个分支的指向以及项目的分支分叉情况。
git log --oneline --decorate --graph --all
查看分支
查看本地分支
git branch
查看所有分支(包括远程分支)
git branch -a
查看本地分支最后一次的提交
git branch -v
合并分支
当我们在新建的工作分支上修复了bug或者加入了新的内容时,可以将其合并到主分支上,首先切换到主分支,然后利用git merge命令进行合并。
git checkout master
git merge testing
删除分支
git branch -d testing
克隆指定分支
git clone -b testing https://github.com/528405176/hello-world
删除远程分支
git push --delete origin testing
重命名本地分支
git branch -m testing newtest
解决本地仓库与远程仓库不一致问题
pull远程仓库
git pull origin
然后和本地仓库合并
git merge origin master
最后提交
git push origin master
参考资料:
https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%85%B3%E4%BA%8E%E7%89%88%E6%9C%AC%E6%8E%A7%E5%88%B6