Git学习笔记

最近在学习廖雪峰的Git教程【链接】,记录下学习过程以便日后查阅。

ps:实际上一个月前已经把该教程撸了一遍了,但是项目中都没用到,忘的差不多了哈哈,今天有空赶紧来复习一下,让我们正式开始吧。

 

a

一、创建版本库

初始化一个Git仓库,使用git init命令。

添加文件到Git仓库,分两步:

  第一步,使用命令git add <file>,注意,可反复多次使用,添加多个文件;

  第二步,使用命令git commit,完成。

1、创建一个版本库非常简单。我们先创建一个名为learngit的空目录:

 为了避免出现不必要的麻烦,请确保目录名(包括父目录)不包含中文

1 $ mkdir learngit   //创建learngit文件夹
2 $ cd learngit    //进入该文件夹

 

  2、通过 git init 命令把这个目录变成Git可以管理的仓库:

1 $ git init

 

  3、现在我们编写一个readme.txt文件并放到learngit目录下,内容如下:

1 Git is a version control system.
2 Git is free software.

 

   用命令 git add 告诉Git,把文件添加到仓库:

1 $ git add readme.txt  //执行该命令,没有任何显示,这就对了

 

  用命令 git commit 告诉Git,把文件提交到仓库:

1 $ git commit -m "wrote a readme file"
2 [master (root-commit) cb926e7] wrote a readme file
3  1 file changed, 2 insertions(+)
4  create mode 100644 readme.txt

  -m 后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

 

  你可以添加多个文件之后再提交:

1 $ git add file1.txt
2 $ git add file2.txt file3.txt
3 $ git commit -m "add 3 files."

 

二、时光机穿梭

  1. 要随时掌握工作区的状态,使用 git status 命令。
  2. 如果 git status 告诉你有文件被修改过,用 git diff 可以查看修改内容。

  我们继续修改readme.txt文件,改成如下内容:

1 Git is a distributed version control system.
2 Git is free software.

  

  git status 命令可以让我们时刻掌握仓库当前的状态

  运行 git status 命令看看结果:

1 $ git status

  

  git diff 顾名思义就是查看difference

  用 git diff 这个命令看看前后区别:

1 $ git diff readme.txt 

  

  最后再用 git add -> git commit -m "xxx" 提交,"xxx"内容为备注信息

 

  (1)版本回退

HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令 git reset --hard commit_id 

穿梭前,用 git log 可以查看提交历史,以便确定要回退到哪个版本。

要重返未来,用 git reflog 查看命令历史,以便确定要回到未来的哪个版本。

  git log 查看历史版本记录

  假定我们现在readme.txt修改之后提交了2次,那么现在就有三个版本,可用 git log 来查看历史版本记录

  如果嫌输出信息太多,看得眼花缭乱的,可以试试加上 --pretty=oneline 参数:

1 1 $ git log --pretty=oneline
2 2 3628164fb26d48395383f8f31179f24e0882e1e0 append GPL       //3628164...882e1e0的是commit id(版本号) 
3 3 ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
4 4 cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

   git reset --hard commit_id 可以回退到上一个版本

  commit_id的值可以为:HEAD^(代表上一个版本)、HEAD^^(上上个版本)、HEAD~100(前第100个版本),

也可以为代表版本号的数字。版本号没必要写全,前几位就可以了,Git会自动去找。

1 $ git reset --hard 3628164
2 HEAD is now at 3628164 append GPL

  git reflog 用来记录你的每一次命令

  你可以用 git reflog 命令来查看命令记录,方便将版本还原成最新版本

1 $ git reflog
2 ea34578 HEAD@{0}: reset: moving to HEAD^
3 3628164 HEAD@{1}: commit: append GPL
4 ea34578 HEAD@{2}: commit: add distributed
5 cb926e7 HEAD@{3}: commit (initial): wrote a readme file

  (2)工作区与暂存区

  工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。

    Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD

前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:

  第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区;

  第二步是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支。

 

因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在 git commit 就是往master分支上提交更改。

你可以简单理解为,需要提交的文件修改通通放到暂存区,然后一次性提交暂存区的所有修改

  工作区与暂存区

  (3)管理修改

    将readme.txt修改一次并用 git add 命令将其添加到暂存区之后,再次修改readme.txt,然后用 git commit -m "xxx" 将其提交,你会发现只有第一次的修改被提交了。

  这是因为在工作区的第二次修改并没有放入暂存区,所以,git commit 只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

  

  正确的流程:第一次修改 -> git add -> 第二次修改 -> git add -> git commit

  (4)撤销修改

场景1:当你改乱了工作区某个文件的内容,想直接丢弃工作区的修改时,用命令 git checkout -- file 

场景2:当你不但改乱了工作区某个文件的内容,还添加到了暂存区时,想丢弃修改,分两步:

    第一步用命令 git reset HEAD file,就回到了场景1。

    第二步按场景1操作。

场景3:已经提交了不合适的修改到版本库时,想要撤销本次提交,参考 版本回退 一节,不过前提是没有推送到远程库。

命令 git checkout -- readme.txt 意思就是,把 readme.txt 文件在工作区的修改全部撤销,这里有两种情况:

  一种是 readme.txt 自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;

  一种是 readme.txt 已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

总之,就是让这个文件回到最近一次 git commit 或 git add 时的状态。

 

  (5)删除文件

  当你将工作区的一个文件 git add 提交到暂存区并且 git commit -m "xxx" 到版本库之后,将工作区的文件删除。这时工作区和版本库就不同了,你有两种选择:

  1、你也想将版本库的该文件删除,那就用命令 git rm 删掉,并且 git commit

1 $ git rm test.txt
2 rm 'test.txt'
3 $ git commit -m "remove test.txt"
4 [master d17efd8] remove test.txt
5  1 file changed, 1 deletion(-)
6  delete mode 100644 test.txt

  2、刚刚的删除是误删,我想恢复工作区的该文件:

   git checkout 其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

1 $ git checkout -- test.txt

 

三、远程仓库

  (1)添加远程库 

要关联一个远程库,使用命令 git remote add origin git@github.com:cutPicturesMan/learngit2.git

关联后,使用命令 git push -u origin master 第一次推送master分支的所有内容;

此后,每次本地提交后,只要有必要,就可以使用命令 git push origin master 推送最新修改;

修改关联的远程仓库:

  方法一:git remote set-url origin URL

  方法二:1、先删除 git remote rm origin 

      2、再添加新的地址 git remote add origin git@github.com:cutPicturesMan/learngit3.git 

 

  (2)从远程库克隆

  首先,登陆GitHub,创建一个新的仓库,下一步是用命令 git clone 克隆一个本地库

1 $ git clone git@github.com:cutPicturesMan/clone.git
2 Cloning into 'gitskills'... 3 remote: Counting objects: 3, done. 4 remote: Total 3 (delta 0), reused 0 (delta 0) 5 Receiving objects: 100% (3/3), done. 6 7 $ cd gitskills 8 $ ls 9 README.md

  Git支持多种协议,包括https,但通过ssh支持的原生git协议速度最快。

四、分支管理 

  (1)创建与合并分支

查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

  一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点: 

  当前主分支

  当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

  Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!

  创建dev分支

  不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变

   dev分支前移,master不变

  假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

   分支合并

所以Git合并分支也很快!就改改指针,工作区内容也不变!

合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

   删除dev分支

  (2)解决冲突

  在master主分支上新建一个分支feature,修改text.txt内容并 git add text.txt -> git commit -m "feature" git checkout master 返回master主分支

  在master主分支上修改text.txt内容并 git add text.txt -> git commit -m "master" 到主分支

  现在,master分支和feature1分支各自都分别有新的提交,变成了这样:

  master主分支和feature分支

  这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突

1 $ git merge feature1  //无法合并
Auto-merging readme.txt
CONFLICT (content): Merge conflict in readme.txt
Automatic merge failed; fix conflicts and then commit the result.

  必须手动解决冲突后再提交。

  修改text.txt内容并 git add text.txt -> git commit -m "conflict fixed" 后,master分支和feature1分支变成了下图所示:

  修改后合并

  

   用带参数的 git log 也可以看到分支的合并情况:

1 $ git log --graph --pretty=oneline --abbrev-commit
2 *   59bc1cb conflict fixed
3 |
4 | * 75a857c AND simple
5 * | 400b400 & simple
6 |/
7 * fec145a branch test

  最后 git branch -d feature 删除分支,工作完成。

  

  

原文地址:https://www.cnblogs.com/cutPicturesMan/p/5399665.html