Git基本使用(一)

125 阅读8分钟

Git

Git简介

Git是目前世界上最先进的分布式版本控制系统

Git安装和配置

在官网下载安装程序,然后默认安装即可,安装完成后,在任意文件夹右键可以找到git bash

image-20220925210111389.png

用户配置

安装完成后,还需要设置,在命令行输入

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

设置机器的用户名和用户邮箱,注意git config命令的--global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。单独的设置不加globle就可以。参考:

it 提供了一个叫做 git config 的工具(译注:实际是 git-config 命令,只不过可以通过 git 加一个名字来呼叫此命令。),专门用来配置或读取相应的工作环境变量。而正是由这些环境变量,决定了 Git 在各个环节的具体工作方式和行为。这些变量可以存放在以下三个不同的地方:

  • /etc/gitconfig 文件:系统中对所有用户都普遍适用的配置。若使用 git config 时用 --system 选项,读写的就是这个文件。
  • ~/.gitconfig 文件:用户目录下的配置文件只适用于该用户。若使用 git config 时用 --global 选项,读写的就是这个文件。
  • 当前仓库的 Git 目录中的配置文件(也就是工作目录中的 .git/config 文件):这里的配置仅仅针对当前仓库有效。每一个级别的配置都会覆盖上层的相同配置,所以 .git/config 里的配置会覆盖 /etc/gitconfig 中的同名变量。

Windows 系统上,Git 会找寻用户主目录下的 .gitconfig 文件。主目录即 HOME 变量指定的目录,一般都是 C:\Documents and Settings$USER。此外,Git 还会尝试找寻 /etc/gitconfig 文件,只不过看当初 Git 装在什么目录,就以此作为根目录来定位。

如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的仓库都会默认使用这里配置的用户信息。如果要在某个特定的仓库中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前仓库的 .git/config 文件里。

如果你是使用 https 进行仓库的推拉,你可能需要配置客户端记住密码,避免每次都输入密码

$ git config --global credential.helper store

文本编辑器配置

接下来要设置的是默认使用的文本编辑器。Git 需要你输入一些额外消息的时候,会自动调用一个外部文本编辑器给你用。默认会使用操作系统指定的默认编辑器,一般可能会是 Vi 或者 Vim。如果你有其他偏好,比如 Emacs 的话,可以重新设置:

$ git config --global core.editor emacs

差异分析工具 还有一个比较常用的是,在解决合并冲突时使用哪种差异分析工具。比如要改用 vimdiff 的话:

$ git config --global merge.tool vimdiff

Git 可以理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合并工具的输出信息。当然,你也可以指定使用自己开发的工具。

查看配置信息

要检查已有的配置信息,可以使用 git config --list 命令:

$ git config --list
user.name=Scott Chacon
user.email=schacon@gmail.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...

有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。

也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:

$ git config user.name
Scott Chacon

创建版本库

版本库即为仓库,英文为repository,可以简单理解成一个目录,这个目录中的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能追踪,以便任何时刻都可以追踪历史,或者在将来的某个时刻可以还原。创建一个库很简单,在一个目录中通过 git init命令即可创建一个git仓库。创建后,目录中会多出一个.git的目录,这个目录是git来跟踪管理版本库的,不能轻易改动。

image-20220925214201900.png

注意

  • 所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。
  • Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件
  • 千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等。

创建一个test.txt文件,内容如下

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

第一步,用git add命令,让git把文件添加到仓库

git add test.txt

第二步,使用git commit命令告诉git把文件提交到仓库

git commit -m "wrote a file"

git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,git commit执行成功后会告诉你,1 file changed:1个文件被改动(我们新添加的test.txt文件);2 insertions:插入了两行内容。

image-20220925214830602.png

git add一次可以添加一个或多个文件

git add [file1] [file2] //添加多个文件
git add [dir] //添加指定目录到暂存区,包括子目录
git add . //将当前目录下的所有文件添加到暂存区

版本控制

状态查看

我们已经成功添加并提交了一个test.txt文件,继续修改test.txt文件,改为

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

这时运行git status命令结果为

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt
​
no changes added to commit (use "git add" and/or "git commit -a")
​

git status命令可以查看git仓库当前的状态,上面的命令输出的含义为,test.txt被修改过,但还没有准备提交的修改。

虽然通过 status可以知道test.txt被修改了,但不知道具体修改的内容,可以通过git diff来查看

$ git diff test.txt
diff --git a/test.txt b/test.txt
index d8036c1..013b5bc 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1,2 @@
-Git is a version control system.
+Git is a distributed version control system.
 Git is free software.
\ No newline at end of file
​

git diff就是查看difference,显示格式为Uni通用的diff格式,可以从上面的命令输出看到,我们在第一行添加了一个distributed单词。提交修改和提交新文件是一样的两步,第一步是git add

git add test.txt

在执行第二步git commit之前,我们再运行git status查看当前仓库的状态:

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.txt

git status告诉我们,将要被提交的修改包括test.txt

第二步就是提交git commit -m

$ git commit -m "add distributed"
[master 9ec8740] add distributed
1 file changed, 1 insertion(+), 1 deletion(-)

提交后,再用git status命令查看仓库的当前状态:

$ git status
On branch master
nothing to commit, working tree clean

git告诉我们当前没有需要提交的修改,而且,工作目录是干净的。

版本回退

再修改一次test.txt,改为:

Git is a distributed version control system.
Git is free software distributed under the GPL.

然后提交

git add test.txt
git commit -m "append GPL"

目前,已经有三个版本被提交到了git仓库中了:

版本一:git commit test

Git is a version control system.
Git is free software

版本二:append distributed

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

版本三:append GPL

Git is a distributed version control system.
Git is free software distributed under the GPL.

在实际工作中,用git log可以查看每次的改动了什么内容

$ git log
commit 716e6f4972bfaa4b6d3458c8c27239223230f216 (HEAD -> master)
Author: pengrui.niu <pengrui.niu@qunar.com>
Date:   Sun Sep 25 23:10:09 2022 +0800

    append GPL

commit 9ec8740e5e53fa58f27af087c25bb62059ed4e05
Author: pengrui.niu <pengrui.niu@qunar.com>
Date:   Sun Sep 25 22:32:51 2022 +0800

    add distributed

commit 5326625fae08b380ceeb27df69e0d97fc7015da4
Author: pengrui.niu <pengrui.niu@qunar.com>
Date:   Sun Sep 25 21:48:16 2022 +0800

    git commit test

git log命令显示从最近到最远的提交日志,能够看到三次提交,最近一次提交时append GPL,上一次是add distributed,最早的一次是git commit test。在命令后加上--pretty=oneline参数,可以简化信息:

$ git log --pretty=oneline
716e6f4972bfaa4b6d3458c8c27239223230f216 (HEAD -> master) append GPL
9ec8740e5e53fa58f27af087c25bb62059ed4e05 add distributed
5326625fae08b380ceeb27df69e0d97fc7015da4 git commit test

如果想把test.txt回退到上一个版本,也就是 add distributed版本。首先要知道当前是哪个版本,在git中,用HEAD表示当前版本,上一个版本是HEAD^,上上个版本是HEAD^^,往上100个版本是HEAD~100

把当前版本append GPL回退到上一个版本add distributed,使用git reset命令。

$ git reset --hard HEAD^
HEAD is now at 9ec8740 add distributed

此时用git log查看当前版本库日志

$ git log
commit 9ec8740e5e53fa58f27af087c25bb62059ed4e05 (HEAD -> master)
Author: pengrui.niu <pengrui.niu@qunar.com>
Date:   Sun Sep 25 22:32:51 2022 +0800

    add distributed

commit 5326625fae08b380ceeb27df69e0d97fc7015da4
Author: pengrui.niu <pengrui.niu@qunar.com>
Date:   Sun Sep 25 21:48:16 2022 +0800

    git commit test

最新的append GPL已经不见了,此时如果想回到append GPL,窗口没关的话,往上翻,可以通过之前的那个版本的commit id回去,id不需要写全,写前几位就可以。

$ git reset --hard 716e
HEAD is now at 716e6f4 append GPL

但是如果把窗口关了后,再想回到这个版本的话怎么办呢。需要commit id,git提供了一个命令git reflog用来记录每一次的命令:

$ git reflog
716e6f4 (HEAD -> master) HEAD@{0}: reset: moving to 716e
9ec8740 HEAD@{1}: reset: moving to HEAD^
716e6f4 (HEAD -> master) HEAD@{2}: commit: append GPL
9ec8740 HEAD@{3}: commit: add distributed
5326625 HEAD@{4}: commit (initial): git commit test

这样知道commit id后,就可以跳到任意版本了。

工作区和暂存区

工作区(Working Directory):就是电脑里看到的目录,比如gittest2就是一个工作区

image-20220927000448411.png

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

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

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

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

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

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

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

管理修改

为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。比如,在test.txt中新加一行Git tracks changes.

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git tracks changes.

然后add,再查看状态

$ git add test.txt
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.txt

然后再修改

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git tracks changes of files.

然后commit

$ git commit -m "git tracks changes"
[master 8fb43d3] git tracks changes
 1 file changed, 2 insertions(+), 1 deletion(-)

然后再查看状态

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt

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

可以看到第二次的修改没有被提交,我们的操作过程为:第一次修改->git add->第二次修改->git commit

因为git管理的是修改,所以,当使用git add命令后,在工作区的第一次修改被放入了暂存区,准备提交,但是在工作区的第二次修改并没有放入暂存区,所以git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。怎么提交第二次修改呢?你可以继续git addgit commit,也可以别着急提交第一次修改,先git add第二次修改,再git commit,就相当于把两次修改合并后一块提交了:

第一次修改 -> git add -> 第二次修改 -> git add -> git commit

撤销修改

使用git checkout -- file可以丢弃工作区的修改这里有两种情况:

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

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

添加一行 Git aaaaaaaa,还没有add到暂存区。

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git tracks changes of files.
Git aaaaaaaa

执行命令git checkout -- test.txt

再次查看文件,文件已经被复原。

Git is a distributed version control system.
Git is free software distributed under the GPL.
Git tracks changes of files.

如果文件修改后,并且已经add到了暂存区,那么如果想把暂存区的修改回退到工作区,可使用命令git reset HEAD <file>,使用HEAD,表示最新的版本。

在文件中添加一行aaa然后add到暂存区,此时查看git status,修改已经被add,还未commit

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.txt

此时执行命令git reset HEAD test.txt

$ git reset HEAD test.txt
Unstaged changes after reset:
M       test.txt

执行成功,此时在查看状态git status,现在暂存区是干净的,工作区有修改。

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   test.txt

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

git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。

删除文件

在git中,删除也是一个修改操作,先创建一个新文件testrm.txt并提交

此时在文件夹中把这个文件删除,此时git知道了删除操作,因此工作区和版本库就版本不一致了,执行git status就可以知道那些文件被删除了。

$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    testrm.txt

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

如果想从版本库中删除该文件,就使用命令git rm删除,并且commit。如果并不是真的想删除文件,那就可以通过命令git checkout -- testrm.txt将文件恢复到最新版本,但是要小心,只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容

参考:www.liaoxuefeng.com/wiki/896043…