title: 基础Git技能 date: 2016/9/23 20:59:00 categories: 笔记 tags: - Git fancybox: comments: true permalink: description: 一些基础的Git技能,放到这里备忘。 --- 首先[廖雪峰的Git教程](http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000) ## 帮助 `git {xxx} --help` ## 配置 ### 用户信息配置 ``` git config --global user.name "John Doe" git config --global user.email johndoe@example.com ``` 这里`--global`是全局 如果想使用不同的用户不加这个参数配置就好。 ### 文本编辑器配置 `git config --global core.editor emacs` ### 查看配置信息 全部 `git config --list` 某一个 `git config ` ## 获取 Git 仓库 ### 在当前目录新建一个Git代码库 `git init` ### 新建一个目录,将其初始化为Git代码库 `git init [project-name]` ### 下载一个项目和它的整个代码历史 `git clone [url]` ### 获取到远程库 首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库 如果本地需上传的仓库为learngit,运行以下命令: `git remote add origin git@github.com:michaelliao/learngit.git` 需要将`michaelliao`更换为自己的用户名。 添加后,远程库的名字就是`origin`,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。 下一步,就可以把本地库的所有内容推送到远程库上: `git push -u origin master` 不过在push之前需要`git add .`跟踪文件`git commit`提交后push之后远程库才能同步。 此后,每次本地提交后,只要有必要,就可以使用命令`git push origin master`推送最新修改 ### 更新 ``` git pull ``` ## 跟踪文件 使用命令`git add`开始跟踪一个文件,或者把已跟踪的已修改的文件放到临时存储区域。这个命令有很多参数可以选择,可通过`git add --help`来了解,不过最常用的是两种: ``` ### 跟踪一个具体的文件 git add ### 跟踪所有文件 git add . ``` 工作目录下的每一个文件都不外乎这两种状态:已跟踪或未跟踪。 已跟踪的文件是指那些被纳入了版本控制的文件。工作目录中除已跟踪文件以外的所有其它文件都属于未跟踪文件(废话)。 初次克隆某个仓库的时候,工作目录中的所有文件都属于已跟踪文件,并处于未修改状态。 ### 忽略某些文件 一般我们总会有些文件无需纳入 Git 的管理。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 更典型的场景是,我们获得了一份JAVA工程源码,在本地我们需要用eclipse来进行开发,eclipse会为项目生成`.classpath` `.project` `.settings`等eclipse特有的文件(夹),还会自动编译源码,产出的`.class`文件放在bin目录下。这几个文件和bin文件夹,都没必要进行控制,因为他们会自动生成,不同的开发环境和编译环境的产出并不相同,我们只需把src目录下所有东西用git管理起来就行。 在这种情况下,我们可以创建一个名为 .gitignore 的文件,列出要忽略的文件模式。 来看一个实际的例子: ``` *.class # 忽略clsss文件 # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar #忽略jar包 *.war *.ear # eclipse files # .project .classpath .settings/ ``` GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore 文件列表,你可以在[https://github.com/github/gitignore](https://github.com/github/gitignore) 找到它. ## 检查当前文件状态 要查看哪些文件处于什么状态,可以用`git status`命令。我们现在有1.txt,可以新增一个2.txt,然后运行`git status`,可以看到status命令不仅列出了文件状态,还对下一步应该使用的命令给出了提示,很棒! ## 提交 `git commit` 这种方式会启动文本编辑器以便输入本次提交的说明。如果你不熟悉当前系统的文本编辑器的使用(如vi),你也可以在commit 命令后添加 `-m` 选项,将提交信息与命令放在同一行,如下所示: ``` git commit -m "第一次提交1.txt" ``` 注释随便写的,建议正式项目中写更为具体的注释,以便大家知道你具体干了什么。 ## 三种状态 Git 有三种状态,你的文件可能处于其中之一:**已修改(modified)**、**已暂存(staged)**和**已提交(committed)**。 - 已修改表示修改了文件,但还没跟踪,如新增的文件和刚修改过的文件。 - 已暂存表示对一个已修改文件的当前版本做了标记(`git add`)。 - 已提交表示数据已经安全地保存在本地数据库中(`git commit`)。 由此引入 Git 项目的三个工作区域的概念:**工作目录**、**暂存区域**以及**Git仓库**。 - 工作目录是放在磁盘上供你使用或修改的文件及目录总和。 - 暂存区域是一个文件,缓存文件快照,有时候也被称作“索引”,不过一般说法还是叫暂存区域。 - Git仓库是 Git 用来保存项目的元数据和文件快照的地方,记录了所有历史提交。 基本的 Git 工作流程如下: 1. 在工作目录中修改文件。 2. 暂存文件(`git add`),将文件的快照放入暂存区域。 3. 提交更新(`git commit`),找到暂存区域的文件,将快照永久性存储到 Git 仓库。 需要注意的是,文件快照必须先经过暂存区,才能到仓库区。盘点之前的操作,1.txt经过暂存并提交,现在进入了本地仓库,但是2.txt未进行add操作,因此本地仓库里面其实没有2.txt的记录。 现在我们暂存并提交下2.txt: ``` git add . git commit -m "第一次提交2.txt" ``` ### 提交的才是安全的 现在我们在操作系统里面删掉1.txt并尝试恢复: ``` rm 1.txt ll #查看文件列表,1.txt没了 git checkout . ll #查看文件列表,1.txt回来了 ``` checkout命令我们暂时不解释,这里只证明提交了就安全了,可恢复了。相比之下,如果没有提交,直接删掉文件除了从回收站找以外没别的办法,如果回收站被清空了,那就真的丢失了。 ## 关于提交的其他命令 ### 跳过暂存区域直接提交 尽管使用暂存区域的方式可以精心准备要提交的细节,但有时候这么做略显繁琐。 Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给 `git commit` 加上 `-a` 选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 `git add` 步骤. ### 查看提交历史 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史. 完成这个任务最简单而又有效的工具是 `git log` 命令。 在目录下运行 `git log` 默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。 正如你所看到的,这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。 `git log` 有许多选项可以帮助你搜寻你所要找的提交, 接下来我们介绍些最常用的。 - 一个常用的选项是 `-p`,用来显示每次提交的内容差异。 你也可以加上 -2 来仅显示最近两次提交 - 如果你想看到每次提交的简略的统计信息,你可以使用 `--stat` 选项. - 另外一个常用的选项是 `--pretty`。 这个选项可以指定使用不同于默认格式的方式展示提交历史。 这个选项有一些内建的子选项供你使用。 比如用 oneline 将每个提交放在一行显示,查看的提交数很大时非常有用。 另外还有`short`,`full` 和 `fuller` 可以用,展示的信息或多或少有些不同 ``` git log --pretty=oneline ``` ## 文件对比 ### 对比工作区与暂存区 ``` cat 2.txt #查看2.txt的内容222 vi 2.txt #新增一行为333 git diff -- 2.txt #比对工作区和暂存区(上次暂存)的区别 ``` 得到的提示前面是一些基本信息,文件对比细节在@@之后,+表示新增,-表示删除,行前无符号表示未改变。 ### 对比暂存区和仓库区 也就是比对缓存快照和已经提交的快照 ``` git diff --cached -- 2.txt ``` 结果显示无差异,因为上一次缓存的都提交了,接下来这样尝试: ``` git add . #所有文件缓存快照 git diff --cached -- 2.txt #比对2.txt的暂存快照和提交快照 ``` 得到的效果和上上次实验一样,因为2.txt增加一行后的快照已经暂存,但是还没提交,所以对比下,暂存快照比已提交快照多了一行。 ### 对比工作区和仓库区 也就是得到自上次提交以来文件的变化,命令必须带上`commit_id`或者基于HEAD的运算(HEAD~是最后一个`commit_id`): ``` git diff HEAD~ -- 2.txt ``` 对比效果和上次一样,因为新增的一行就是上次提交以来的所有变化。 ### 对比两次提交之间的差异 ``` git log --pretty=oneline b037a33258f9582c2d70e130b62b699df7900280 删除3.txt 54da1fe001be58c7fc41f6d3aac0e35166b8cb4a 首次提交3.txt 2abf7fb7ca06bd3a3eadc85471c41a340134d249 第一次提交2.txt 976ea66c800dee7ce3c69601e31518f2ef721237 第一次提交1.txt ``` 然后对比第一和第二次提交的差异: ``` git diff 976ea66c 2abf7fb7 ``` 注意,这里我们使用了简写的`commit_id`,因为只要简写能完全标识一次提交,没有必要使用完整的`commit_id`. 第二次提交相对于第一次提交来说,增加了一个文件,文件里面增加了内容。 这个命令可以带上文件路径,如:`git diff 976ea66c 2abf7fb7 -- 2.txt`,当然结果是一样的,因为只有2.txt有变化。 ## 移除文件 之前我们移除并恢复过1.txt文件,但这与“从版本库中移除文件”并不相同。要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 `git rm `命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。 如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项`-f`(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删还没有添加到快照的数据,这样的数据不能被 Git 恢复。 另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加`.gitignore`文件,不小心把一个很大的日志文件或一堆`.a `这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用`--cached`选项: ``` cd lesson1 echo 333>3.txt git add . git commit -m "首次提交3.txt" git rm --cached 3.txt ll #查看文件列表,3.txt还在 git status #3.txt显示为未跟踪 #编辑.gitignore,添加3.txt git add . git commit -m "删除3.txt" ``` 这样处理之后,3.txt仍然在本地,但是会被git忽略掉。