一、引言
大多数学校每年都会有一个学年论文,大多数同学在写学年论文时都会进行不同版本的修订,假设初稿写好之后就是第一个版本,由于学年论文有许多要求,一不留神就会出现错误。所以,一般的同学会将其另存为,然后在另存的这个版本上进行修改,如果修改的这个版本比较合适,就选用第二个版本,如果修订的版本不如前一个版本,就会选用第一个版本。那么,git就是这样一个工具,为了防止项目丢失,更改失误,失误后能恢复到原来的版本,帮助我们在程序开发时进行项目的版本控制。
二、Git的历史
linus在1991年创建了开源的Linux,但是Linux的壮大是靠全世界热心的志愿者参与,那么问题就来了,这么多人位居世界各地,是Linux的代码是如何管理的呢?
2002年前,志愿者将代码发给Linus,Linus通过手工合并代码,但是这样的方法不是很合适,大家表示不太满意。于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover处于人道主义,授权Linux社区免费试用这个版本控制系统。
但是在2005年时,Linux社区牛人云集,Andrew带头开始试图破解BitKeeper的协议,被BitMover公司发现了,于是收回了Linux社区的免费使用权。
Linus花了两周的时间用C写了一个分布式版本控制系统,就是Git,2008年GitHub网站上线,为开源项目免费提供Git存储,无数开源项目开始迁移到GitHub。
Git是分布式版本,为了更好的去容灾,防止编程过程中出现重大失误,方便多人合作。
三、Git的使用
创建一个目录文件,切换到当前目录下,然后将第三方仓库克隆到本地仓库。
[zwe@localhost 桌面]$ mkdir testgit
[zwe@localhost 桌面]$ cd testgit/
[zwe@localhost testgit]$ git clone https://github.com/zwe7616175/test.git
正克隆到 'test'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
展开对象中: 100% (3/3), 完成.
检查连接... 完成。
[zwe@localhost testgit]$ ls
test
git支持多种协议,包括https,但通过ssh支持的原生git协议速度快。
git入门(add&commit&push)
1.git add 把文件添加到仓库。
2.git commit 把文件提交到仓库,-m是本次提交的说明。
3.git push 将本地分支的更新,推送到远程主机。
git push <远程主机名> <本地分支名>:<远程分支名>
[zwe@localhost test]$ git add test.c
[zwe@localhost test]$ git commit -m "add zhushi"
[master 9968d33] add zhushi
1 file changed, 2 insertions(+)
[zwe@localhost test]$ git status
位于分支 master
您的分支领先 'origin/master' 共 1 个提交。
(使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
[zwe@localhost test]$ git push
对象计数中: 3, 完成.
压缩对象中: 100% (3/3), 完成.
写入对象中: 100% (3/3), 318 bytes | 0 bytes/s, 完成.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/zwe7616175/test.git
313b72d..9968d33 master -> master
总结:
git add实际上是将要提交的所有修改放到暂存区,然后执行git commit就可以一次性将暂存区的所有修改提交到分支。一旦提交后,如果你没有对工作区做任何修改,那么工作区就是“干净”的。
git push将本地库的内容推送到远程,实际上是将当前分支master推送到远程。第一次推送master分支的所有内容使用命令:git push -u origin master。后序可采用git push origin master推送最新修改。
其他重要的操作
1.git status
查看结果:
[zwe@localhost test]$ git status
位于分支 dev
您的分支与上游分支 'origin/dev' 一致。
无文件要提交,干净的工作区
修改后查看结果:
[zwe@localhost test]$ git status
位于分支 dev
您的分支与上游分支 'origin/dev' 一致。
尚未暂存以备提交的变更:
(使用 "git add <file>..." 更新要提交的内容)
(使用 "git checkout -- <file>..." 丢弃工作区的改动)
修改: test.c
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
2.git diff
提示修改的内容,顾名思义就是查看difference,显示的格式是Unix通用的diff格式。
[zwe@localhost test]$ git diff
diff --git a/test.c b/test.c
index f52e37b..10642f2 100644
--- a/test.c
+++ b/test.c
@@ -3,6 +3,5 @@
int main()
{
printf("hello\n");
- printf("hello\n");
return 0;
}
要随时掌握工作区的状态,使用git status命令。
如果git status告诉你有文件被修改过,用git diff可以查看修改内容。
3.git log/git log –pretty=oneline
git log是用于打印日志文件,git log –pretty=oneline也是打印日志文件,是按行打印的。
[zwe@localhost test]$ git log
commit 9968d33c819605436dd0184d3de9b9e7b9c110fb
Author: zwe <zhaowaner668@163.com>
Date: Sat Sep 1 08:23:23 2018 -0700
add zhushi
commit 313b72d0396fe04118fe3596ff6a6b4bc20f4f5a
Author: zwe <zwe@localhost.localdomain>
Date: Sat Sep 1 07:53:42 2018 -0700
change README.md
[zwe@localhost test]$ git log --pretty=oneline
9968d33c819605436dd0184d3de9b9e7b9c110fb add zhushi
313b72d0396fe04118fe3596ff6a6b4bc20f4f5a change README.md
4aff41734b970af71f44fcc7b9019ce2e0268e8e add test.c
38d4fdc33bc7ae0914c608dd3f9d35bbd414a13f branch test
c86a4ee3585fa55e87d0db99f110d7e62694afa7 test.c add printf
82d42ec8f742811aba491f26f6f2934baf97b8b3 add test
3ee7db2530947d01ef73f097e74be625d0659631 add test
dfea40795e13497e6cd5b65d46eaa9b82ea8b4ff Create README.md
4.git reset –hard [回退版本的commit ID]
[zwe@localhost test]$ git reset --hard 313b72d0396fe04118fe3596ff6a6b4bc20f4f5a
HEAD 现在位于 313b72d change README.md
heads下的master指向当前版本ID。
5.git reflog
查询历史记录,找到所有回退的内容。
分支管理
每次提交,git都将所有版本串成一条时间线,这个时间线就是一个分支。Git有一个主分支,即master分支,HEAD严格来说不是指向提交的,而是指向master,master才是指向提交的,所以,HEAD指向的是当前分支。
分支操作
1.git branch dev
创建分支。
git checkout dev
切换分支
git checkout -b dev
创建分支并切过去。
[zwe@localhost test]$ git branch dev
[zwe@localhost test]$ git checkout -b dec
切换到一个新分支 'dec'
[zwe@localhost test]$ git branch
* dec
dev
master
HEAD指向master分支,也称主分支,当前在哪个分支,哪个分支前就有个*标识。
git checkout –file
加上–,意思是将file文件在工作区的修改全部撤销掉。
2.git merge dev
合并分支实际上就是将两个分支指向当前的分支。
3.git branch -d dev
删除分支。
4.git stash
将当前的工作区暂存起来。
5.git stash pop
恢复当前工作区。
在我们编写代码的过程中,往往会遇到这种问题,就是正在一个分支上编写代码,然后领导告诉你主分支上有一个BUG需要修改,这时,你当前分支的内容写了一半,还无法提交,但是又要修改主分支上的BUG,就需要将当前的工作区暂存起来,然后另创建一个分支进行修改,修改完成后,再等恢复现场后继续工作。
解决冲突
当Git无法自动合并分支时,就需要先解决冲突,解决冲突后,再提交,合并完成。解决冲突最好是手动解决,将Git合并失败的文件手动编辑成我们希望的内容,再进行提交。
可以使用 git log –graph命令查看到分支合并图。
分支管理
分支合并,不将–no-ff参数是用fast forward进行合并的,不会生成提交信息,合并后看不出来曾经做过合并,如果加上–no-ff可以做普通模式合并,会生成提交信息,合并后的历史有分支,可以看出曾经做过合并。
多人协作工作模式
1.试图将自己的修改推送到远端仓库,git push origin <branch-name>;
2.如果推送失败,原因可能是远程分支比本地分支更新,需要先用 git pull试图合并;
3.如果合并还存在冲突,则解决冲突,并在本地进行提交;
4.如果没有冲突或解决了冲突,用 git push origin <branch-name>推送就可以成功;
标签管理
发布一个版本时,我们通常先在版本库中打一个标签,这样就唯一确定了打标签时刻的版本,将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。
1.git tag v0.1 ID
打标签,方便进行回滚。
2.git -d tag v0.1
删除标签。
3.git push origin –tage
将全部标签推送到远程。