Git起步

Git起步

注:本文仅针对于git初学或之前未接触版本控制工具的同学,希望能帮助大家快速入门。

温馨提示:
大家可跟着文章一步步去操作,建议先用一个试验的demo去学习操作。如果直接用真实的合作项目练习,误操作有可能会存在坑队友的情况。

1. 关于版本控制

在进入主题之前,我们先来了解一下版本控制。我们在使用一个工具前,一定要明确自己在做什么,这个工具给我们带来什么好处。所谓版本控制,其实就是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的记录系统。简而言之,就是假如你在做一个项目,项目在不断迭代开发,代码就会有变化。借助版本控制工具,你就能查看不同版本的差别,方便你找到你想要的版本,并能通过一个简单的操作或命令就能回到你想要的版本。有或者,你在做这个项目时,是与其他人一起合作,你们分别负责其中一部分。最后,通过版本控制工具,可以很方便的将你们的代码合并子在一起。

所以,我们可以看出,版本控制就是简化迭代开发和多人合作的工具。Git就是一款年轻而轻巧的版本控制工具。具体的很多概念我们不做赘述,本文的主旨就是Git的快速入门。

在实际工作中多人合作以及项目开发最频繁的操作:
1.将多人合作项目从远程仓库获取到本地;
2.提交修改;
3.建立本地分支;
4.同步远程更新;
5.推送更新至远程;
6.分支合并;
7.删除本地分支和远程分支;
8.查看日志和差别。

2. 准备工作

在一切项目开始之前,我们需先安装Git。Git的安装方法还是很多的,最简单的方法可以去官网下载安装文件来进行安装。如果安装了Homebrew,执行

sudo brew install git

命令就可以安装了。其他的安装方法(如通过源码安装等)就不赘述,感兴趣的同学可以自己深入研究。

安装好了Git,首先要完成一些基本的配置。设置用户名称与邮件地址很重要,因为每一个 Git 的提交都会使用这些信息,并且它会写入到你的每一次提交中,不可更改:

git config --global user.name "Your Github Nickname"
git config --global user.email xxx@xxx.xxx

再次强调,如果使用了 –global 选项,那么该命令只需要运行一次,因为之后无论你在该系统上做任何事情, Git 都会使用那些信息。 当你想针对特定项目使用不同的用户名称与邮件地址时,可以在那个项目目录下运行没有 –global 选项的命令来配置。

再者,介绍一个比较常用的命令:

git config --list

查看当前的所有配置信息,包括用户名、邮箱、默认的打开编辑器及分支关联信息等。

3. 建立项目和初始化操作

完成了基本配置,我们可以开始项目了。如果是对本地现有项目进行管理,执行

git init

将创建一个名为 .git 的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。

不过,本文针对的还是基于已有的远程仓库,实现多人合作开发。执行以下命令([url]为github上项目的地址)。

git clone [url]

就可将远程仓库的项目代码复制到本地,且完成了初始化操作。即多人合作项目在本地就有一个副本了,我们可以通过这个副本来做自己的任务开发了。

4. 提交修改

有了项目,假如我们现在在项目中做了修改,会如何呢?我们先了解几个概念。地仓库由 Git维护的三棵“树”组成。第一个是你的工作目录,它持有实际文件;第二个是缓存区(Index),它像个缓存区域,临时保存你的改动;最后是HEAD,指向你最近一次提交后的结果。如图:

我们如果对项目的文件进行了增删改等一系列操作,产生了文件的差异,则Git会将文件标记为modified(新增文件标记为new file;删除文件标记为deleted),此时这些文件就处于暂存状态。这时我们可以开始学习一个重要的相关命令。

git status

通过这个命令,我们可以查看当前文件的状态。其实这个命令在每一步都可以使用,它的作用是查看当前的文件状态,后续操作我们还会使用到这个命令。

例如,我在项目中编辑了一个README.md文件执行这个命令,显示如下:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

此时,我们就看到了文件的README.md文件处于更改的暂存状态。下一步我们就用该将暂存文件加入缓存中。细心的同学应该发现了,在显示内容的提示中,Git已经告诉我们下一步该怎么做了。

git add <file>

通过这个add命令,我们就能将想要添加的文件加入缓存区域。其中file指的就是文件名。加入我一次修改的文件比较多,想批量加入,则将用“*”或者“.”代替即可。如下:

git add *

这时,我们再执行git status查看,就如下显示:

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   README.md

Git又一次提示我们下一步该怎么做了。现在,通过add指令,我们的文件已经加入缓存区了。即图片中的index对应的状态。我们要生成一个版本快照,在执行如下指令即可:

git commit -m 'edit your message at here'

在-m参数后,我们可以编辑我们的版本显示信息。这样一来,我们的修改编辑操作就完成了,生成了一个新的版本快照。细心的同学可能在add操作时,看提示信息就又有新发现了,一个叫git reset HEAD <file>的指令。这个指令就是还原add操作。假如我将一个文件添加进缓存了,但是我突然又想改动这个文件,此时直接修改是会产生两个不同版本的冲突。其实,通过这个命令撤销加入缓存的操作,将文件改为暂存状态,我们就可以继续编辑了。

回到主线上来,当我们完成了一个版本的修改后,并生成了快照,我们就应该发布了,这样远程的仓库也会得到更新。但是,我们先不着急推送,我们还需要在之前加入一个非常关键的步骤。

5. 建立本地分支和获取远程分支

其实,在实际项目中,多人协作开发,是有不同的分支的,每个人都在自己的分支上开发自己的功能,最后将大家的功能合并在一起,就完成了一次协作。所以,之前说的需要加入的关键步骤就是新建分支。

首先,我们简单了解一下分支是做什么的。 Git对数据的保存,原理是记录一系列不同时刻的文件快照。Git的分支,其实本质上是指向提交对象的可变指针。Git的默认分支名字是master。 在多次提交操作之后,你其实已经有一个指向最后那个提交对象的master分支。 它会在每次的提交操作中自动向前移动。我们实际项目中,master分支是用来稳定版本的,大家的操作都是从master上再重新拉出一个新的分支。然后在这个新分支上做自己的项目研发。

我们通过

git branch

就可以查看本地分支了。
新建一个分支的操作就是在此命令后加上分支名。

git branch <分支名>

比如,我们可以通过git branch testing来创建一个名为testing的分支。此时具有master和testing两个分支。如图:

有了多个分支,我们就可以通过

git checkout <分支名>

来切换到对应的分支名下。

Git中有个名为 HEAD 的特殊指针,它能指向当前分支。如,当我们切换到testing分支下,就如下图所示:

git branch命令查看,就能发现当前分支前有“*”号标记。

$ git branch
  master
* testing

上述的新建并切换到新分支操作,可以合并成一个命令:

git checkout -b <分支名>

当然,有时候,我们可能会将远程仓库的分支获取到本地。这时,我们执行下面这个命令:

git checkout -b <本地分支名> origin/<远程分支名>

为了方便起见,通常本地分支名和远程分支名用同一个名称。例如,将远程的test分支获取到本地,执行git checkout -b test origin/test即可。其中的origin指的就是远程仓库,origin是默认的命名。

6. 同步远程更新

现在,我们已经知道如何建立一个新分支了,也知道如何将更新作为一个快照提交了。现在要做是不是能提交到远程更新了呢?先不着急提交。我们还需要完成一个更新操作。因为我们本地开发,假如我们的合作伙伴也完成了开发,而且将更新提交到了远程仓库,这时候远程的仓库就会因为他的提交,使得版本向前推进。而我们本地的版本还是比较早的,所以,我们需呀同步一下远程仓库而使得本地的版本也是最新的。我们借用一个简单的指令:

git pull

这个指令其实是两个操作的结合(操作可拆分,但我们这里暂不做详细说明),就是更新和合并操作(合并内容后面会给大家说明)。

其实,这个命令,就是将远程的版本更新同步到本地,并将当前分支对应的远程分支更新的内容也合并到本地分支。

但是,如果是新的分支,那么在执行这个指令时,会提示找不到关联的分支。如下所示:

There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> test

这是因为git pull这个指令是将默认的分支远程同名分支相关联的,新建的本地分支还没有与之关联的远程分支。--set-upstream表示的意思就是增加关联。这时,我们可以按照提示的信息去解决这个问题,会提示找不到相关的远程分支。但是我们不必着急。我们接着学习下一步内容,问题自然就会解决。

7. 推送更新至远程

我们在本地新建了分支,只是在本地存在而已,我们要将新内容更新到远程,就可以执行以下指令:

git push

这时,就能把更新的内容推送到远程了。但是,新分支就不会这么顺利,它会显示如下信息:

$ git push
fatal: The current branch test has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin test

信息提示就很明确了,我们只需要执行git push --set-upstream origin test就能将本地分支推送到远程。这时,远程仓库中就会有我们的新分支并且将我们本地的分支与远程的分支做了关联。
第一次操作新分支,增添了关联,操作此分支,就不用再重复操作了,直接用git pullgit push就可以同步和发布当前分支的内容了。

当然,设置关联的方法还有很多,这里不赘述。还记得之前在准备工作中提到的
git config --list
指令吗,我们通过这个指令就能发现我们的配置增加了新内容。多了一行:

branch.test.remote=origin
branch.test.merge=refs/heads/test

这就是配置信息中添加的关联项。

8. 分支合并

现在,我们知道了如何将修改的内容提交并发送到远程仓库中。但是,既然是多人合作,我们还有关键的一步,就是合并分支。什么事合并分支呢?前面我们也简单提到过了分支的合并。现在,就为大家说明。我们做多人合作项目,每个人的开发任务都在自己的分支上进行。但是一次项目的迭代,可能需要多个人完成不同的功能,最后将这些功能合在一起,就完成了一次迭代。我们要拥有其他人分支上的代码,就要做合并操作。通过:

git merge <目标分支名>

就能将目标分支的代码合并过来了。比如,我在test1分支上开发完成了一个功能,队友在test2上完成了他的功能,最后,我们要将两个人的功能合在一起完成这开发。那么,我们可以这样操作:提交并推送自己的分支修改到远程关联分支,这时,工作目录就是干净的。接下来,如果我们本地没有合作伙伴的分支test2,我们可以将分支从远程获取到本地,如果本地已经存在了test2分支,就可以切换到test2分支上了。通过git pull将test2分支的内容更新,这时我们本地的test2分支就跟远程的内容同步了,即拥有了队友的更新内容。接下来,我们再切换回自己的分支test1,这时候,执行git merge test2就可以将test2分支的更新内容合并到自己的test1分支上了,这时,我们的test1分支就拥有了自己和队友的更新内容了。这时,我们再执行git push就能将远程存库的内容更新了。

当然,这是合并分支最理想的情况了。假如我们和队友同时改动了同一个文件切存在改动差异了,这时就会提示合并失败,通过git status我们可以查看存在冲突的文件,和队友协商修改完冲突文件后,在执行add、commit、push一系列与提交更新并发布相同的指令流程。

9. 删除本地分支和远程分支

有了新建分支、更新和推送的基础,我们可以学习删除分支了。当我们发现有些分支不再需要时,我们可以选择将该分支删除了。删除本地分支,可以通过:

git branch -d <分支名>

就可以删除本地分支了。若分支还处于编辑状态,比如正在merge,执行这个命令是失败的,会提示有文件正在编辑。如果确定删除,我们可以强删。执行:

git branch -D <分支名>

此命令就是强删,慎用,除非很确定。

如果该分支还有远程关联的分支,我们还需要把远程仓库中的分支删除,执行:

git push origin :<分支名>

就可以删除远程的该分支了,原理很简单,就相当于push了一个空分支去覆盖了远程的这个分支,实现了删除的效果。当然,高版本的Git提供了新方法:

git push origin --delete <分支名>

注意,这个命令中如果将--delete参数简写成-d是无效的。

10. 查看日志和差别

在发布前或发布后,查看一下提交日志是个好习惯。通过

git log

就能查看到所有的提交记录。其中的一些参数就不赘述了。再者,就是文件差异。使用

git diff 

可查看暂存前后的文件差异。通常,我们通过这个指令在add加入缓存前,可以查看编辑的文件和上一个版本的快照差异。若文件已添加暂存,通过

git diff --cached

就可查看加入缓存前后的变化。

结语

相信,看到这里,你已经大致了解了Git和的一些基本使用和原理。本文内容是bootstrap官网Git简易教程
和Git社区参考书前三章内容的学习总结。简易教程以图形化、少内容的方式展示,给我们提供了学习Git的主要命令快捷途径。Git社区参考书内容丰富,从原理剖析,实例化的操作过程,是深入学习Git的极佳途径。本文将两者作为参考,在简易教程的基础上,增加了精简后的Git参考书内容,希望大家能在快速掌握Git使用的同时,也明白操作的原理和文件变化的趋势。

你可能感兴趣的:(git,版本控制,合作,版本控制工具)