赞
踩
最近QQ同学正在基于omnet
开发自己的工程,让她困惑的是:如何记住自己的每次修改?特别是在大型程序开发中,这并不是一件容易的事情。不过我们可以通过git
来辅助管理代码改动,更妙的是,我们还能将其上传到代码托管网站,如github
,gitee
上,实现多人同时开发。本文将分别从git
的基本概念,git
的使用,将git
上传到github
三个方面阐述git的用法。
什么是git
呢?不严谨的来说,git
实际上是对每次提交做一次快照(snapshot
),并且管理这一系列快照的工具。
如上图所示,github
由三个区组成,分别是工作区、暂存区以及 Git
目录。并且这三个部分可以通过箭头的形式进行转换。
git add
可以将结果存入暂存区。git add
后,对此时的工作区做快照,存在暂存区,此时文件状态为已暂存(staged)。用户可以在工作区继续修改,通过git add
多次更新快照。结束修改后,通过git commit
添加一些对此次修改的描述,并进行提交。Git
目录:当提交完修改后,这笔提交就正式存入了Git
目录中。可以使用git log
查看每笔提交的具体内容。我们向云端的代码仓上传和下载的也是这个部分的内容。1. 使用`git -v`查看你本地是否有`git`。如果没有,请根据你的平台,对应下载`git`工具。
2. 在合适的位置新建一个文件夹,使用`git init`来初始化git仓库。
git status
来查看工作区此时的情况Changes not staged for commit
:这说明git管理的文件中出现了修改。Untracked files
: 说明用户新建了文件,并且此文件尚未被git
跟踪,需要手动使用git add <filename>
通知git
对其进行管理。当然,我们还可以通过git add
加上一些选项,全部或部分的对修改进行管理。
以下是这个阶段常用的一些命令:
命令 | 含义 |
---|---|
git status | 查看此时工作区的状态 |
git diff | 查看此时工作区尚未保存到暂存区的,所有已被追踪的文件的具体变化 |
git restore | 丢弃某些修改 |
git add <file> | 提交单个文件变化 |
git add -A | 提交所有变化 |
git add -u | 提交被修改(modified)和被删除(deleted)的文件, 不包括新文件(new |
git add . | 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件 |
git add -h | git add 查看帮助,git add --help可以查看更详细内容 |
tips: 在每次提交前使用
git status
查看工作区状态是一个好习惯,它能确保我们每次提交不会遗漏修改!
前面已经说到,可以使用git commit
写入评论信息。此处可能需要使用到vim
,vim
是一款常用于linux
,macos
下的文件编辑器,如果你对它的操作不熟悉,请自行谷歌学习。
按照提示输入信息后退出,使用git log
,我们就可以看到刚刚的提交了。
当你想多次提交到同一个commit中,请使用git commit --amend。
学完了上述内容,相信你还有很多疑问。比如说,我已经将某次修改提交到了git目录或是暂存区,但此时发现修改不对,难道要再重新手动把它改回来吗?是否有更便捷的方法呢?或是我想基于一份代码做多种修改,难道需要本地创建多个git仓库?这些问题在开发中每天都会遇到,接下来让我们一一解决它们。
让我们回到git log
显示的信息。这次让我们关注一些细节。
可以看到commit后面跟了一串数字,我们把它叫做commit id,这是通过哈希算法得出的哈希值,在这里,我们只要知道这个值是唯一的,也就是说,每笔提交都拥有独一无二的commit id。
为了满足基于一份代码做多种修改的需求,git
提出了branch
的概念。何为branch
,实际上是一个可以移动的指针。使用git branch testing
,新建一个名为testing
的新分支。再次使用git log
查看git
目录,可以看到多了一个testing
的分支。
此时的git
目录如图所示:
98ca9,34ac2,f30ab
指代三次commit
的commit id
,提交顺序为98ca9 -> 34ac2 -> f30ab
。
注意:HEAD
是一个特殊的指针,它永远指向当前branch
的最新一笔提交。
接下来使用git checkout testing
切换到已经存在的分支, 可以看到HEAD
指针此时指向了testing
分支。
此时git
目录就变为了:
我们再进行一次提交,会看到此时的testing
指针向前移动,指向了最新一次提交的commit id
。而master
的指针却不会移动。
让我们使用git checkout master
切换回master
分支,可以看到HEAD
指向了master
。并且git log
中,最新的commit
不见了。
由此可以知道,利用branch
的特性,我们可以在任意commit
处创建新的branch
,并且不同的branch
之间互不影响。
假设QQ已经进行了三次提交,commit id
为 a - b - c
,此时QQ同学突然发现自己需要退回到a时候的状态,她要怎么做呢?前面我们讲到,git
使用HEAD
指针来指示此分支的最后一笔提交,那我们可以将HEAD
和分支的指针都指向某一个commit id
处。而git reset
就是这样的命令。
针对刚刚的场景,QQ同学可以采用 git reset --hard a
,让指针重新指向commit id
为 a 处,也可以使用git reset --hard HEAD~2
。来让HEAD
的指针回退2个提交。
此外,git reset
不仅可以用来回退,只要你知道commit id
,HEAD
指针也可以重新指向commit c
的位置。
如果你很不幸的忘记了自己是如何移动HEAD
指针的,也没有关系。使用git reflog
可以查看你的每次操作。
第一部分是HEAD每次操作指向的commit id
,这里使用的较短的哈希值,和git log
中的长哈希值是对应的,也等效于HEAD@{i}
,也就是说使用git reset --hard 99678a8
与git reset --hard HEAD@{4}
是等效的。
第二部分可以看到,git reflog
还显示了当时指向commit id
的对应指针。
要注意,git reset的本质是移动指针,请你思考一下,在这种情况下,使用
git reset --hard 87ab2
,git目录是怎样变化的呢?
Git
目录的相互切换Git
目录回到暂存区
前面我们讲到如何使用git reset --hard
,而其实还有一个非常相似的命令git reset --soft
。它的区别是,此时会将这条commit
的内容回退到暂存区,我们可以重新使用git commit
来将它提交到git目录。
暂存区回到工作区
使用git reset [file]
回退单个文件或是git reset
回退所有文件。
[1] https://git-scm.com/docs/user-manual/en
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。