Learn Git in One hour

Learn Git in One hour

本系列文章,受到Learn X in Y minutes以及知乎-哪些技能,经较短时间的学习,就可以给人的生活带来巨大帮助?等系列教程、文章的启发。

本文为Learn X in One hour系列文章第一篇,重点在Git入门,希望读完本文后,您就可以开始使用Git进行工作了。


##零、Git安装,基本概念 ####0.安装

Windows系统: 去下载msysgit然后安装就可以了。提供了Git bash和Git GUI供大家使用,我们这里主要介绍的是bash的命令行操作。

Linux系统(Debian或Ubuntu Linux): sudo apt-get install git

其他的一些系统大家可以网上搜一下,比较简单。

安装完成后,我们需要配置一些用户名

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

####1.版本号(commit-id) : 一个SHA1计算出来的一个非常大的数字,用十六进制表示,代表每一次commit,一般使用前6位即可。 Alt text

####2.HEAD指针: 表示当前版本,HEAD~{n}表示当前版本之前的第n个版本

####3.工作区(Working Directory)和 版本库(Repository) Alt text 版本库类似于我们玩游戏的存档区,每一次提交到版本库,就有一个存档记录(save),方便日后进行回退(load),而存档的名字,就是版本号(commit-id)

####4.暂存区(stage) 和 分支(branch) Alt text

通过add放入暂存区,在通过commit提交到当前分支,只有被放入暂存区的文件,才能最终被提交。我们可以多次add然后统一commit,提交到版本库。

未追踪状态(Untracked):从未被放入过暂存区

##一、最简流程及常用命令

  • git init : 初始化 首先需要把一个普通文件夹初始化为一个git仓库

  • git add <file> <file_1>....:加入缓存区

  • git commit -m "commit message":提交缓存区内容到分支

  • git status : 查看状态 查看当前版本库的状态

  • git diff : 对比变化 查看文件改动前后的变化

  • git log:查看提交记录
    git log --pretty=oneline
    git reflog :查看命令历史

  • git push origin master : 推送到远端仓库origin/master

Alt text 大部分时候,我们只是在循环使用这几个命令。 其中我们经常会使用git status来查看当前状态:

Alt text

新创建了test.md后,会提示找到未追踪的文件。

Alt text

修改后,尚未添加到暂存区(commit不会将其提交)

Alt text

添加到了暂存区(commit会将其提交)

Alt text

运行commit之后,暂存区被提交。工作区干净(git没有发现工作区的任何改动)

##二、回退与删除

回退大法好

我们经常会需要对版本进行回退,这种回退可能发生在各个阶段,git都能够很好很方便的操作,这也是git强大的地方。

###0.查看版本 回退首先要查看版本,不然我们没办法确定要回退到什么位置。此处会用到HEAD版本号两个东西。以及git log命令

使用git log或者git log --oneline可以查看我们之前的commit记录,也就是我们之前的存档。

Alt text

###1.尚未暂存(before add) git checkout -- <file>:丢弃工作区修改。注意是工作区,对暂存区和版本库用此命令是无法修改的

git reset HEAD <file>: 丢弃暂存区的修改(unstage)

###2.尚未提交(before commit)

  • 暂存区有修改可以提交!

  • 撤销当前暂存区的修改

  • 暂存区全部修改被撤销,工作区有未暂存的文件!

###3.已经提交(after commit before push) 回退版本,回退后,工作区和暂存区都是干净的。(–hard一定,其他不一定) git reset <commit-id>,Git会把HEAD指针,指向我们回退的那个版本。

Alt text

###4.已经推送(after push) 首先把本地回退,然后git push -f origin master进行强行推送,如果不使用-f,则出现non-fast-forward错误。

###5.删除文件 在工作区,删除文件后,用git status 会检测到有文件被删除(工作区),如果我们确实要删除,则使用git rm来删除(同时会进行暂存,类似于add),然后,git status会检测到有文件被删除(暂存区),此时我们已经可以提交了。 当然,删除也是一种修改,我们可以使用回退大法来撤销我们的修改。

所有被提交到版本库的文件,都不需要担心误删,我们可以通过回退来找回文件,但是回退是有代价

##三、远程仓库(coding socially) ###1. SSH key $ ssh-keygen -t rsa -C "youremail@example.com" 将会在用户主目录里生成.ssh目录,里面有id_rsaid_rsa.pub两个文件,如果你已经有了这两个文件,就不需要上述操作了。 绑定SSH key到GitHub

###2. 创建并添加远程仓库 git remote add origin git@github.com:hanxiaomax/learngit.git 远程库的名字默认是origin

###3. 推送 git push -u origin master -u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。 ` git push origin master`

###4. 克隆 git clone git@github.com:hanxiaomax/gitskills.git

###5. 多种协议 httpsssh

https://github.com/hanxiaomax/hanxiaomax.github.io.git 如果添加的仓库地址是这样的,则在push时需要输入密码,因为是https方式。 ssh方式更为方便,速度也比较快。

##四、分支管理

###1. 简介 分支是git系统非常重要的一部分,我们可以认为Git世界并非仅有一条时间线,我们可以在不同的时间线上开发,然后合并。当然,这之间不能有冲突。。

###2. 创建分支 git checkout -b dev创建并切换分支 相当于

git branch dev 创建分支
git checkout dev 切换分支

###3. 查看分支 git branch 当前分支前面会有*

###4. 合并分支 合并B分支到A首先需要合并切换到A分支,然后使用git merge B 其中涉及到比如fast-forward方式什么的,可以看这个问题:git merge –no-ff是什么意思

###5. 删除分支 git branch -d <name>

###6. 分支冲突 假设我们从master创建了一个分支dev,然后进行了一些修改,同时,master分支也进行了一些修改,很显然,在master和dev直接,可能对同一个部分进行了不同的修改,这样在我们合并他们的时候,就会产生冲突。 git merge dev 会报告有冲突,那么我们使用git status 来查看具体冲突
Git用<<<<<<<=======>>>>>>>标记出不同分支的内容,我们需要人工的对冲突处进行确认和取舍,选择两者之一或者进行其他的修改。修改此处为我们需要的状态。再次add,commit

###7. 分支树 git log --graph --pretty=oneline --abbrev-commit

###8. fast-forward方式 fast-forward方式是指在合并时,master的指针直接指向当前分支。当可以使用fast-forward方式时,git会尽量使用它。 git merge dev 但是这种情况下,如果删除分支,则会丢失分支信息,我们可以强制关闭fast-forward方式: git merge --no-ff -m "no-ff" dev 这样git会在合并时,创建一个commit,所以自然我们需要写commit massage

###9. 良好的分支习惯 通常我们不希望在master上面直接开发,而是把master当做成品仓库,只有当准备发布新版本时才会去向master合并。 因此,我们首先会创建一个dev分支,然后大家从这个分支把代码克隆到自己的机器上进行开发,并时常的进行提交和推送,在dev分支上进行合并。然后在某个大版本完成准备发布的时候,把dev合并到master即可。

###10. 紧急bug分支(在工作区未提交时创建分支) 请查看: git stash 暂存 git stash list 查看 git stash apply 恢复 git stash drop 删除

###11. 强制删除分支 git branch -D <branch-name>

###12. 推送分支 git remote查看远程仓库 git push origin master 推送本地master分支到远程仓库origin的master分支 git push origin dev 推送本地dev分支到远程仓库origin的dev分支。

###13. 抓取分支 git clone git@github.com:hanxiaomax/learngit.git 如果这样clone的话,在本地只能master分支

如果需要其他分支: git checkout -b dev origin/dev 这样,会在本地创建dev分支,并且把它和远端origin分支的dev对应起来。同时,切换到dev分支。 当我们向远端分支提交时,可能会遇到non-fast-forward,这种情况有几种处理方式:

1):强行上传git push -f origin master,这种方式一般不用,因为会把远端的更新的文件,替换为本地较旧的文件,不过如果你像远端推送了不希望推送的内容,可以用这种方法删除。 2):解决冲突 git pull可以先把远端仓库最新的代码拉到本地,此时会自动向本地分支合并,此时会遇到冲突。解决冲突,然后再次提交,上传。

##五、GitHub

假设有项目仓库A,你想要参与:

  1. fork仓库A。因为你没有权限向A直接推送,它是属于仓库原主人的(你的ssh key不在它的列表中)。
  2. clone仓库A。下面你需要clone fork后的仓库yours/A到本地,进行开发
  3. push。把你写的代码先push到你的yours/A仓库中。
  4. pull request向原仓库A的主人申请,让他从远端把你yours/A仓库中代码pull到远端仓库A。至此,就完成了贡献代码。

##六、忽略文件 创建.gitignore文件,可以让git不去追踪某些不必要的文件。

/:目录;
*:通配符
?:通配符
[]:单字符匹配列表
!:不忽略

只适用于还未添加到git中的文件,如果已经添加,需要先用git rm来删除

如果需要让git管理一个空文件夹,则在该文件夹下建立一个.gitignore文件,内容为

# Ignore everything in this directory 
* 
# Except this file !.gitignore 

##七、参考文件及扩展阅读:


本文采用中国大陆版CC协议发布
作者保留以下权利:

  1. 署名(Attribution):必须提到原作者。
  2. 非商业用途(Noncommercial):不得用于盈利性目的。
  3. 禁止演绎(No Derivative Works):不得修改原作品, 不得再创作。
    新浪微博 @XX含笑饮砒霜XX