Git使用笔记
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。为了将平时写的一些代码托管到Github,有必要学习一下git的基本使用方法。怕自己忘记了,撰写学习笔记如下:
配置Git
Git跟踪项目必须配置用户名和电子邮件。当然如果一开始没有设置,在第一次提交时Git也会提示输入相关信息。
1
2$ git config --global user.name "username"
$ git config --global user.email "[email protected]"
创建项目
创建一个项目,即创建一个文件夹,将相关文件保存在文件夹内。譬如,创建名为git_pratice的文件,并初始化仓库:
1 | $ git init |
输出表明Git在git_practice文件夹中初始化了一个空仓库。仓库是程序中被Git主动跟踪的一组文件,这些文件都存储在隐藏文件夹.git中,因此千万不要去更改这个文件夹,更不能删除。
将文件加入仓库
检查状态
项目已经创建,我们先用git status
来看看项目的状态:
1 | $ git status |
在Git中,分枝(branch)是项目的一个版本。从上述输出可以看出,我们位于分枝master上。后面的输出表明,当前尚未进行任何提交,并且无可提交内容(毕竟当前文件夹为空么)。
将文件加入仓库
在git_pratice文件夹中新建Python程序文件hello_world.py,我们将使用这个文件来探索Git的基本功能。然后,我们再用git status
来看看项目的状态:
1 | $ git status |
根据输出信息,可以发现Git已经发现hello_world.py文件,并提示用git add <file>
将文件加入仓库:
1 | $ git add . |
命令git add .
表示将项目中未被跟踪的所有文件都加入到仓库,它不提交这些文件,而只是让Git开始关注这些文件。标签new
file意味着这些文件是新添加到仓库的。
忽略文件
有时候文件下会产生一些我们无需跟踪的文件,譬如Python程序会在执行.py文件时产生.pyc的文件,并自动保存在_pycache_
目录中。为了让Git忽略这个目录,可以创建一个名为.gitignore的特殊文件,其内容为:_pycache_
。这样可以让Git忽略该目录下的所有文件。这个例子里,我并没有创建这个文件,所以如果你创建了,下面的实例可能会略有差异。
执行提交
第一次提交
下面执行第一次提交:
1 | $ git commit -m "started project" |
执行命令git commit -m “started project”
进行提交,-m
参数后面跟的是记录信息,记录信息被记录到项目的历史记录中便于查看变化。反馈输出信息显示,1个文件发生了改变。再后的状态检查显示,工作目录是干净的。
查看提交历史
Git记录所有的项目提交,可以通过git log
查看历史:
1
2
3
4
5
6$ git log
commit 1f964320343750dd72c8adcb580589034df7df48 (HEAD -> master)
Author: Bruce <[email protected]>
Date: Wed Jan 22 16:26:25 2020 +0800
started project
每次提交时,Git都会生成一个40个字符长度的唯一ID,它记录了谁提交的、提交时间和提交描述信息。Git还提供了一个选项,让我们能够打印提交历史条目的简洁版本:
1 | $ git log --prettty=oneline |
标记--pretty=oneline
指定显示两项最重要信息:提交ID和提交描述信息。
第二次提交
为了展示版本控制的强大威力,我们对项目进行修改:在hello_world.py中再添加一行代码。然后我们来查看项目状态:
1 | $ git status |
可以发现,Git注意到了这个文件发生了变化。输出指出了我们当前所在的分枝、被修改文件的名称,并指出所做的修改尚未提交。下面我们来提交所做的修改,并查看状态:
1 | $ git commit -am "Extending greetings" |
我们再次执行了提交,并在执行命令git commit
时指定了标记-am
,标记a
表示将仓库中所有修改了的文件都加入到当前提交中(如果两次提交中间又创建了新文件,可再次执行git add .
将这些文件加入到仓库)。标记m
用于记录提交信息。
撤销修改
撤销修改
为了展示撤销修改功能,我们对hello_world.py进行修改,再加入一行代码print('Oh, no!.')
,并保存这个文件。我们查看状态
,可以发现Git已经注意到了所做的修改。
1 | $ git status |
如果修改是我们想要的,我们可以如前所示进行提交。但如果不是我们要得,而要恢复到最后一个提交。为此,我们不在文本编辑器中对hello_world.py执行任何操作,而是在终端中执行如下命令:
1 | $ git checkout . |
命令git checkout .
放弃最后一次提交后所做的修改,将项目恢复到最后一次提交的状态。我们使用文本编辑器打开hello_world.py,发现其已经恢复到之前的版本。
检出到以前的提交
我们可以检出到提交历史中的任何一个版本,而不仅仅是最后一次提交,为此可以在命令git checkout
后面加指定提交ID的前6个字符,而不是.
。
1 | $ git log --pretty=oneline |
检出以前的历史版本后,将离开分枝master,并进入Git所说的分离头指针(detached
HEAD)。查看hello_world.py文件,发现现在里面只有语句print('Hello World!'),即回到了初始状态。
如果要回到分枝master,可以如下操作:
1 | $ git checkout master |
这让我们重新回到了分枝master。如果查看hello_world.py文件的话,它里面又有两句输出了。除非使用Git高级功能,否则在检出历史提交后最好不要对项目做任何修改。当然如果参与项目的开发人员只有你自己,而你又想放弃最近的提交,并恢复到以前的状态。为此,可以如下操作:
1 | $ git log --pretty=oneline |
查看状态,可以发现我们依然在分枝master上,而历史记录显示我们已经恢复到第一次提交的历史版本。
分枝与合并
分枝在本地完成,速度快。要创建一个分枝,我们使用branch
命令,但该命令只是创建一个新分枝,不会将我们带入该分支,所以我们需要使用checkout
命令来更改分枝。
1 | $ git branch test |
对于其他分支的更改不会反映在主分支master上。如果想将更改提交到主分支,则需切换到master分枝,然后合并。譬如,我们修改hello_world.py,增加print("this is for test brance")
,然后提交。最后切换到master,并合并分枝test。
1 | $ git status |
查看hello_world.py文件,发现新增的语句已经合进去。如果想删除分枝,我们使用-d
标识。
1 | $ git branch -d test |
发布与取回
发布版本
上述操作后,所有的文件依然存放在本机上。很多时候,尤其是多人写作开发时,开发者都会将项目发不到Git服务器上,进行协作开发。GitHub是世界上最有名的通过Git进行版本控制的软件源代码托管服务平台,本博客的代码示例都会发布在我的GitHub上。
我们先从服务器上克隆一个库
1 | $ git clone ssh://example.com/~/www/project.git |
对克隆后的文件修改后可以再推送到服务器上。
1 | $ git push ssh://example.com/~/www/project.git |
取回更新
如果已经安装上述命令进行push,下面的命令则表示当前分支自动与唯一一个追踪分枝进行合并,即更新。
1 | $ git pull |
如果从非默认位置更新,需指定url。
1 | $ git pull http://git.example.com/project.git |
删除
删除文件
如果想从仓库中删除文件,我们使用rm
:
1 | $ git rm filename |
仓库
如果仓库的历史记录搞乱了,而又不知道如何恢复。在这种情况下应对寻求项目小组其他成员帮助。如果项目开发人员只有自己一个人,可继续使用这些文件,但要将项目的历史记录阐述,即删除.git目录。这不会影响任何文件的当前状态,只会删除所有的提交,因此无法检出项目的其他记录而已。删除.git文件夹后,可以重新git init
进行初始化。
参考文献
[1] 埃里克·马瑟斯. Python编程. Translated by 袁国忠. 图灵程序设计丛书·Python系列 ISBN: 9787115428028. 人民邮电出版社, 2016.
[2] Git五分钟教程