参考资料:廖雪峰git教程
版本控制这个概念不知道大家有没有听说过,不管你是软件开发还是平时写文章或者毕业设计的论文都要有版本管理这个意识,因为我自己在这个上面吃过不少亏。
git命令的学习可以使自己能够更好完成自己的工作以及版本的管理,这也是我自己最想总结git这个命令的原因。
Git是目前世界上最先进的分布式版本控制系统(没有之一),在Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub(国外的平台),国内也有这样的平台码云。
注:可以了解一下集中式与分布式的区别
甚至你必须使用一个文件来记录每个版本的变化,非常的不方便,对于涉及到几个人对一个项目的操作时,合并就更加麻烦,而git能够很好的解决和处理这些问题。
$ git
The program 'git' is currently not installed. You can install it by typing:
$ sudo apt-get install git
查看是否安装:直接在Linux终端输入git,如果没安装就继续输入:sudo apt-get install git
安装完成后,还需要最后一步设置,在命令行输入:
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
注意git config命令的–global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址
仓库又叫版本库(repository),你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,包括:每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”
创建过程如下:
## 首先选择一个合适的地方创建一个空目录:
$ mkdir learngit
$ cd learngit
## 查看目录路径
$ pwd
/dwj/home/learngit
## 初始化仓库
$ git init
Initialized empty Git repository in /dwj/home/learngit/.git/
注:
1. mkdir +仓库名:mkdir可以简记make+dir,pwd是查看当前路径
2. 建立了一个空仓库后,当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,千万不要手动修改这个目录里面的文件,不然很容易将其破坏;如果该目录是隐藏的,用ls -ah命令就可以看见。
* 区别工作区与版本库:*
工作区(working directory):就是你在电脑里能看到的目录
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD.
基本操作:
## 将文件放到learngit目录下,添加文件,将文件加入缓存区(如上图)
$ git add
## 用命令git commit告诉Git,把暂存区的所有内容提交到当前分支,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,以便能从历史记录里方便地找到改动记录()
$ git commit -m "message"
注: 每次修改,如果不add到暂存区,那就不会加入到commit中
其他命令:
1. git status 时刻掌握仓库当前的状态
2. git diff 查看difference
3. git log 查看历史记录,显示从最近到最远的提交日志,如果嫌输出信息太多,看得眼花缭乱的,可以试试加上–pretty=oneline参数,例如:
$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file
注:类似3628164…882e1e0的是commit id(版本号)
4.git reset –hard HEAD^ 表示回到上一个版本
注:在Git中,用HEAD表示当前版本,用HEAD^表示上一个版本,HEAD^^是上上一个版本,更多版本eg:HEAD~100表示 上100个版本。且可以使用git reset –hard commit id(版本号)到指定版本,且版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位。
5. git reflog 查看命令历史,重返未来,以便确定要回到未来的哪个版本
6.git checkout – file 想直接丢弃工作区的修改,必须加–,没有–,就变成了“切换到另一个分支”的命令
7.git reset HEAD file 改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步,第一步用命令git reset HEAD file,就回到工作区,用6的方法修改。
8.git rm 现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm删掉,并且git commit:另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本git checkout –,其实是用版本库里的版本替换工作区的版本:
省略注册【github】以及github的设置等等。
$ git remote add origin 远程仓库名
## eg 远程仓库名:git@github.com:DWJWendy/Weibo_Spider.git
$ git push -u origin master
注:用git push命令,实际上是把当前分支master推送到远程。由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git之后会把本地的master分支和远程的master分支关联起来,所以之后可以不用-u这个参数,直接 git push origin master。
$ git clone 远程仓库名
分支管理是我最想整理的一部分,因为现在需要用上,但是自己还不熟/(ㄒoㄒ)/~~
操作 | 代码 | 备注 |
---|---|---|
查看分支 | git branch | 当前分支会在前标* |
创建分支 | git branch | |
切换分支 | git checkout | |
创建+切换分支 | git checkout -b | |
合并某分支到当前分支 | git merge | |
删除分支 | git branch -d | 合并后删除 |
如果要丢弃一个没有被合并过的分支 | git branch -D | 强行删除 |
下图是一个分支关系图,每次提交,Git都把它们串成一条时间线,在Git里,master是主分支,在下图中,当我们创建了一个新的分支dev时,Git就新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上,我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?就是直接把master指向dev的当前提交,就完成了合并。合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
## 1. 创建分支并切换到分支
$ git checkout -b dev
Switched to a new branch 'dev'
或者
$ git branch dev
$ git checkout dev
Switched to branch 'dev'
## 2.查看分支
$ git branch
* dev
master
## 3.提交
$ git add readme.txt
$ git commit -m "branch test"
[dev fec145a] branch test
1 file changed, 1 insertion(+)
## 4.切换会master
$ git checkout master
Switched to branch 'master‘
## 5.合并
$ git merge dev
Updating d17efd8..fec145a
Fast-forward
readme.txt | 1 +
1 file changed, 1 insertion(+)
## 6. 删除分支
$ git branch -d dev
Deleted branch dev (was fec145a)
Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。强制禁用Fast forward模式,Git需在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。
下面就是–no-ff方式的git merge:
git merge --no-ff -m "merge with no-ff" dev
冲突解决:git告诉我们,文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件。Git会用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改后保存,再提交,用带参数的git log也可以看到分支的合并情况
bug分支:每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。Git还提供了一个stash功能,可以把当前工作现场“储藏”起来 git stash,此时用git status查看工作区,就是干净的,因此可以放心地创建分支来修复bug。
##1. 确定要在哪个分支上修复bug,就在其分支上修复,eg 修复master上的bug,就从master创建临时分支
$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 6 commits.
$ git checkout -b issue-101
Switched to a new branch 'issue-101'
## 2. 修复bug后,提交
## 3. 修复完成后,切换到master分支,并完成合并,最后删除issue-101分支
注:git stash list可以查看刚才的修复,Git把stash内容存在某个地方了,如需恢复有两个办法:一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;另一种方式是用git stash pop,恢复的同时把stash内容也删了:再用git stash list查看,就看不到任何stash内容了,另外你可以多次先用git stash list查看,然后恢复指定的stash,用命令:git stash apply stash@{0}
分支策略
按照几个基本原则进行分支管理:
1.master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
2.干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
3.团队每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了
多人协作
操作 | 代码 | 备注 |
---|---|---|
查看远程库 | git remote | git remote -v显示详细信息 |
推送主分支 | git push origin master | 主分支要时刻与远程同步 |
推送分支 | git push origin | 成员都在dev上工作,因此要与远程同步 |
推送Future分支 | 类似 | 每添加一个新功能,最好新建一个feature分支,开发->合并->删除 |
bug分支 | 类似 | 用于在本地修复bug,就没必要推到远程 |
创建远程分支到本地 | git checkout -b dev origin/dev | 要在dev分支上开发,就必须创建远程origin的dev分支到本地,用这个命令创建本地dev分支 |
我之前在推送代码的时候经常会遇到这样的问题,如下图
解决策略:解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送
小结:
1、查看远程库信息,使用git remote -v;
2、本地新建的分支如果不推送到远程,对其他人就是不可见的;
3、从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
4、在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
5、建立本地分支和远程分支的关联,使用git branch –set-upstream branch-name origin/branch-name;
6、从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。
发布一个版本时,通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本。将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来。
操作 | 代码 | 备注 |
---|---|---|
打一个新标签 | git tag | 默认为HEAD |
查看标签 | git tag | |
对应的commit id打标签 | git tag v0.9 6224937 | 数字是commit id |
查看标签信息 | git show | |
用PGP签名标签 | git tag -s -m “blablabla…” | |
指定标签信息 | git tag -a -m “blablabla…” | |
删除标签 | git tag -d v0.1 | |
推送本地标签 | git push origin | |
推送全部本地标签 | git push origin –tag | 可以推送全部未推送过的本地标签 |
删除远程标签 | git push origin :refs/tags/ |
git使用是必须必须会的,每次遇到就是临时的找命令或者只记住了基础的命令,所以想把它总结下来,之后查的时候也方便。