Git学习记录

学习Git的动机

  • 最近在作毕业设计,写了一个APP。写完以后各类调试,把代码删了改、改了删,不少重复的劳动。尤为是当你修改了代码,发现整个程序崩了,你想要还原成原来能够运行的代码,却又不记得删了什么东西的时候,绝对是十分使人抓狂的。所以在把这个毕设搞完以后,我决心要好好研究一下Git以及Github,把版本控制这个问题好好地解决掉。

Git是啥(做用)

  • Git,官方的解释我就不说了,网上一大堆,我说说个人理解吧。
  1. 最大的做用固然就是对文件每一次的修改进行记录。每修改一次,至关于文件的一个版本。当修改被提交到仓库(Repository)后,Git就会记录下这一次的修改,并做为文件的其中一个版本。当你须要将文件恢复到此次修改前的状态(即放弃此次修改),则直接回退到上一个版本就行。
  2. 除了记录每一次文件的修改,还能够进行协同开发。当两我的都须要修改代码文件时,沟通成本会很高。所以Git能够将代码仓库分红几个分支(branch),每个分支上均可以记录对这个仓库的每一次修改。每个人能够在本身的分支上对文件进行修改、恢复、修改、恢复,你所在的分支会记录下你修改的全部版本。你也无需关注别人对文件修改了什么,只要最后将多我的的分支合并,就能够实现多人对文件进行修改,也就是协同开发。

主要内容

由于这只是一篇学习记录,所以我会简单地介绍一下一些经常使用命令的使用,不会涉及到Git内部的原理、机制。对于Git的操做,主要是使用到git bash。若是读者尚未安装Git的话,能够上网找其余博客学习如何安装。git

1 建立代码版本仓库(Repository)

git bash有点像Linux下的命令行,它会拥有当前工做目录。所以首先,要将当前目录设为你的目标目录。默认的工做目录是:C:/用户/Administrator(你的用户名)。进入到目标目录后,使用git init命令来建立版本库。github

建立成功

2 将文件添加进版本库中

接着,就是将文件添加进版本库中。首先要在当前目录下建立一个文本文件readme.txt,并在文件中写入相应的内容(也就是对文件进行修改)。修改完后,使用git add <file>添加文件(<file>替换为文件名),使用git commit -m <message>将添加后的文件提交至版本库中(<message>替换为此版本的备注信息),做为一个修改版本。其中可使用屡次git add添加多个文件,而后使用一次git commit将多个文件添加进版本库中。bash

添加成功

3 版本回退

修改了文件以后,若是想要将文件恢复到修改前的版本,该咋办?这时就须要使用到命令git reset --hard commit_id或者是git reset --hard HEAD^,其中HEAD^是回退到上一个版本,HEAD^^是回退到上上个版本……。至于commit_id,由于Git对每一次版本的提交,都会分配一个提交版本号(版本号),即commit_id。所以咱们能够经过指定版本号来将文件回退至指定的版本。至于版本号,咱们能够经过命令git log来查看提交记录,就能够从提交记录中查看到版本号。app

在文件中添加新的一行内容

使用git log命令查看提交记录

从上图中咱们能够看出,上一个提交版本的版本号为60084e……。实际上在使用命令时,不须要将版本号一字不漏地敲出来,只须要敲前面几个字符,让系统可以识别出是哪一次提交就能够了。学习

回退成功

从上图中能够看出,readme.txt文件已经恢复到修改前的状态,说明回退成功。然而,我想了想,发现原来的代码并无错,我须要回到刚才恢复前的状态,咋办?依然是使用命令git reset --hard commit_id来实现。然而,使用git log并不能看到将来的版本号(即回退前的版本号),这时就须要使用命令git reflog来查看将来几个版本的版本号。spa

查看回退前的版本号

经过命令git reflog咱们能够看到回退前的版本号为0ebce……,这时就可使用使用命令git reset --hard commit_id使文件恢复到回退前的版本。命令行

恢复成功

4 建立与合并分支

4.1合并分支无冲突

前面的操做都是在默认的主分支master下进行的,可是若是是多人修改文件的话,就须要建立多个子分支,每个分支至关因而一条版本线,最终能够经过分支合并将多个修改后的版本合成最终的版本。
建立分支主要是经过命令git branch <name>实现,切换分支是经过git checkout <name>实现,其中<name>替换为分支名。这两个步骤也能够合起来,使用一条命令git checkout -b <name>来实现。可使用git branch来查看版本库现有的分支。设计

新建并切换分支

切换了分支以后,就能够在这个分支上对文件进行修改,子分支上的修改并不会影响到主分支。不管在子分支上如何修改文件,主分支上的文件都不会受到影响。在子分支上修改完文件后,能够将子分支与主分支合并,使得子分支上修改的文件与主分支上的文件合并。例如,我在子分支dev上对文件进行修改,添加新的一行,并提交至版本库的子分支dev上:版本控制

修改文件,并将结果提交至分支上

这时再使用命令git checkout master切换回主分支,查看主分支上readme.txt文件的内容:调试

主分支上的文件

能够看到,master分支上的文件没有刚才添加的"add dev new line",这就说明dev分支上对文件进行修改,并不会影响到master分支上的文件。
在dev分支上修改完文件后,须要将最终的结果合并到master分支上。可使用命令git merge <name>来实现。也可使用命令git branch -d <name>来删除分支。

将dev分支合并至master分支,并删除dev分支

从文件的输出结果能够看出,将dev分支合并至master分支后,master分支上的文件已经接受了dev分支上对于文件的修改操做,合并成功。最终将dev分支进行删除。在平时的开发中,master分支应该是用来保存最终须要发布的代码的正式版本,而dev分支则是用来保存开发、修改的代码的调试版本。不管在dev分支上如何修改代码,都不会影响到master分支上的正式版代码。

4.2合并分支有冲突

什么叫合并分支有冲突?就是两条分支都修改过文件,在分支合并时就会出现矛盾,Git不知道文件应该怎么合并,这时Git就会提示用户分支冲突。分支冲突以后就须要用户手动进行合并,而后将合并后的文件从新添加、提交至版本库中。

合并冲突

手动合并后再从新提交

4.3保存分支的历史记录(git merge –no-ff)

在使用git merge将子分支与主分支合并后,Git默认使用的是Fast forward模式进行分支合并,这时版本库中不会保存子分支的历史版本信息,以下图的右边所示。若删除子分支后,咱们想查看子分支的历史版本信息则会失败。此外,我在其余博客中还看到说,主分支通常都是发布正式版本的程序,若使用右边的这种合并方式,则会将子分支中的版本信息混入到主分支中,至关于将主分支的历史版本信息弄“浑浊”了,这显然不是咱们想要的结果。这是就须要使用命令git merge –no-ff禁用Fast forward模式进行分支合并,从而达到下图左边的这种效果。子分支删除后,依然能够看到子分支的历史版本信息。合并后会在主分支上提交一个新的版本,这是主分支与子分支合并后的新版本。

两种合并方式的区别

总结廖雪峰老师的Git教程中出现的命令

初始化Git仓库

$ git init

添加文件到Git仓库

// 可屡次添加文件后再提交
$ git add <file> 
$ git commit -m <message>

查看工做区的状态

$ git status

查看修改内容(工做区与暂存区的区别)

$ git diff

回退至任意版本

$ git reset --hard commit_id

查看提交历史

$ git log

查看命令历史(能够查看将来(回退前)提交版本)

$ git reflog

当你改乱了工做区某个文件的内容,想直接丢弃工做区的修改时

$ git checkout -- <file>

当你不但改乱了工做区某个文件的内容,还添加到了暂存区时,想丢弃修改

此场景下分为两步:
先使用命令git reset HEAD <file>回到上一种状况,而后再用解决上一种状况的命令解决。

工做区、暂存区、版本库

删除文件(本地与版本库中的文件均删除)

本地的文件直接删除便可。
删除版本库中的文件须要如下的命令:

// 即先删除后提交
$ git rm test.txt
$ $ git commit -m "remove test.txt"

本地文件误删了,须要从版本库中将文件恢复至本地(前提是本地文件已提交至版本库中)

$ git checkout -- test.txt

将本地Git仓库与远程代码库链接(Github代码库)

$ git remote add origin git@github.com:zhuangbility111/learngit.git

zhuangbility111这个替换为本身的Github帐户名

第一次推送master分支的全部内容至远程库

$ git push -u origin master

之后每一次推送最新修改至远程库

$ git push origin master

从远程库中克隆(下载)代码库至本地代码库(版本库)中

$ git clone git@github.com:zhuangbility111/gitskills.git

与分支相关的命令

// 查看现有分支
$ git branch

// 建立分支
$ git branch <name>

// 切换分支
$ git checkout <name>

// 建立+切换分支
$ git checkout -b <name>

// 合并某分支至当前分支
$ git merge <name>

// 删除分支
$ git branch -d <name> 

// 查看分支合并图
$ git log --graph

// 禁用Fast forward模式进行合并分支(能够查看子分支的历史记录)
$ git merge --no-ff -m <message> dev

保存工做现场,以及恢复工做现场(未提交至版本库中)

// 在未提交至版本库的状况下暂时保存工做现场,切换至其余分支
$ git stash
// 恢复工做现场
$ git stash pop

丢弃一个没有合并过的分支(强行删除)

$ git branch -D <name>

查看远程库(Github代码库)信息

$ git remote -v

从本地推送分支至远程库

// 在本地建立和远程分支对应的分支,`origin/branch-name`为远程库的分支名
$ git checkout -b branch-name origin/branch-name

// 从本地推送分支至远程库
$ git push origin branch-name

// 若是推送失败,则先须要将远程库中的分支读取至本地库,与本地库中对应的分支进行合并
// 若是在将远程库的分支与本地分支合并的过程当中出现冲突,则解决合并冲突,提交至本地库,而后推送至远程库
$ git pull

// 若是git pull提示no tracking information,则说明本地分支和远程分支的连接关系没有建立
// 创建本地分支和远程分支的关联
$ git branch --set-upstream-to <branch-name> origin/<branch-name>

查看历史提交的commit id

$ git log --pretty=oneline --abbrev-commit
12a631b (HEAD -> master, tag: v1.0, origin/master) merged bug fix 101
4c805e2 fix bug 101
e1e9c68 merge with no-ff
f52c633 add merge
cf810e4 conflict fixed
5dc6824 & simple
14096d0 AND simple
b17d20e branch test
d46f35e remove test.txt
b84166e add test.txt
519219b git tracks changes
e43a48b understand how stage works
1094adb append GPL
e475afc add distributed
eaadf4e wrote a readme file

给提交打标签,新建标签(至关于给提交换个别名,而不是使用commit id)

// 查看全部标签
$ git tag

// 默认给当前分支的最新提交设定标签,这个也能够经过commit id来指定给哪个提交打标签
$ git tag <tagname>
$ git tag v0.9 f52c633

// 建立带有说明的标签,用-a指定标签名,-m指定说明文字
$ git tag -a <tagname> -m "blablabla..."
$ git tag -a v0.1 -m "version 0.1 released" 1094adb

// 查看标签说明文字
$ git show <tagname>
$ git show v0.1
tag v0.1
Tagger: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 22:48:43 2018 +0800

version 0.1 released

commit 1094adb7b9b3807259d8cb349e7df1d4d6477073 (tag: v0.1)
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Fri May 18 21:06:15 2018 +0800

    append GPL

diff --git a/readme.txt b/readme.txt
...

操做标签

// 删除标签
$ git tag -d v0.1

// 推送本地库的某个标签至远程库
$ git push origin <tagname>

// 推送所有未推送过的本地标签至远程库
$ git push origin --tags

// 删除本地标签(与第一个相同)
$ git tag -d <tagname>

// 删除远程标签
$ git push origin :refs/tags/<tagname>

写在最后

在今天看完廖雪峰老师的教程后,我很兴奋,因而就急匆匆地写下了这篇博客,权当是一篇学习笔记吧。Git真的是可以帮助我在实际的开发中提升效率的东西。固然,由于我只是刚接触Git,因此此篇博客的内容较简单,都是一些经常使用的操做。还有些我暂时不太理解有什么用处,或者对我来讲暂时用处不大的内容,我都没有提到。等我详细地了解了Git的使用方法,而且熟练使用Git后,我会再继续撰写与Git相关的文章。

相关文章
相关标签/搜索