首页 > 其他 > 详细

学习笔记 | Git

时间:2019-03-02 13:33:27      阅读:135      评论:0      收藏:0      [点我收藏+]

参考(强烈推荐):廖雪峰的 Git 教程。

1. 出发

A. 安装

输入 git 查看是否已安装。

如果没有安装,安装指令: sudo apt-get install git

B. 设置机器身份

Git 是分布式版本控制系统,因此每个机器都需要有对应的 ID :名字和邮箱地址。

我们来设置本台机器的信息:

git config --global user.name "Name"
git config --global user.email "Email address"

--global 的意思是:这台机器上的所有 Git 仓库都使用该信息。

C. 创建版本(仓)库 repository

假设现在有一个文件夹,路径为 /home/xing/MEQE_local

在该目录下,执行: git init ,使得该目录成为 Git 可以管理的仓库。

此时会产生一个隐藏的 .git 目录,可以用 ls -ah 查看到。
该目录是 Git 用以跟踪版本库的,千万不要手动修改。

D. 可管理文件

版本控制系统只能跟踪文本文件的改动,比如 txt ,网页和代码。

对于图片、视频等二进制文件,系统无能为力,只能知道图片大小从 100KB 变成了 120KB 等。

有两点注意:

  1. Word 是二进制格式。
  2. Windows 自带的记事本不要用,会在每个文件开头添加0xefbbbf(十六进制)的字符,导致程序无法正常执行。
    强烈建议使用免费的 Notepad++ 代替 txt ,记得将默认编码设置为 UTF-8 without BOM 。

2. 基础操作

A. 添加文件至仓库

假设我们在该目录下创建了一个 txt 文件,名为 readme.txt
该文件只有一行内容: Git is free software.

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

git add readme.txt

提示: 1 file changed, 1 insertion(+) 。因为添加了一个文件,写了一行。

第二步,正式提交修改:

git commit -m "create a readme file."

如果是多个文件,可以这么操作:

git add file0.txt
git add file1.txt file2.txt file3.txt
git commit -m "add 4 files."

B. 修改文件并查看修改

假设我们加上了新的一行: Keep moving!

此时运行 git status 查看状态,会显示:

On branch master
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.txt

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

这说明: Git 检测到变动: readme.txt ,但是没有准备 (staged) 提交修改 (for commit)的变动 (changes) 。

我们可以用 git diff 查看变动内容:

diff --git a/readme.txt b/readme.txt
index f5b143e..a48528a 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1 +1,2 @@
 Git is free software.
+Keep moving!

最后一行告诉我们,增加了一行 Keep moving!

确认以后,我们再提交到仓库。方法同上一节两步。第一步,要求添加至仓库:

git add readme.txt # 没有任何输出

但此时再查看状态,就不一样了:

git status

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

    modified:   readme.txt

确认将要正式 commit 的文件只有 readme.txt ,那么就可以正式提交了。

再次查看状态,就显示没有文件需要 commit ,并且 working tree clean 。什么意思?后面说。

C. 查看历史变动

每一次 commit ,实际上就是一次存盘,或者说一次快照。

我们可以用 git log 命令查看历史变动:

[master b87e2c5] add a new line.
 1 file changed, 1 insertion(+)
xing@xing:~/MFQE_local$ git log
commit b87e2c5fd623591a510a4873aecdc43793de392e
Author: xing <ryanxingql@foxmail.com>
Date:   Wed Nov 7 21:41:48 2018 +0800

    add a new line.

commit f5c7b7bb1df2455cec90a092ecd231dd8e395bc3
Author: xing <ryanxingql@foxmail.com>
Date:   Wed Nov 7 20:57:11 2018 +0800

    create a readme file

如果我们想让每一次变动只显示一行,可以这么做: git log --pretty=oneline

b87e2c5fd623591a510a4873aecdc43793de392e add a new line.
f5c7b7bb1df2455cec90a092ecd231dd8e395bc3 create a readme file

前面一串是 commit id ,这么复杂的原因,是考虑到分布式修改的使用场景,不能简单地用 1,2,3,...

甚至还可以用可视化工具查看。

D. 版本回退

我们准备把 readme.txt 回退到最初版本,写法是: git reset --hard HEAD^

再查看文件时,已经恢复成最初的模样!

如果想恢复到上上个版本,就是 HEAD^^ 。如果是往上 100 个,那就是 HEAD~100

--hard 参数后面再讲。

此时再查看历史记录:

Author: xing <ryanxingql@foxmail.com>
Date:   Wed Nov 7 20:57:11 2018 +0800

    create a readme file

完了,记录没了,回不去了?

且慢,只要命令行没关,你就可以找到原来的 commit id = b87e2c5fd623591a510a4873aecdc43793de392e ,然后指定 id 回退:

git reset --hard b87e2c5fd623591a510a4873aecdc43793de392e

又恢复成最后的样子了!其实可以只输入 b87e ,Git 会自动去找。

Git 的回退速度非常快,因为本质上是在 Git 内部完成了 HEAD 指针的移动。
HEAD 指针永远指向当前版本。

如果命令行关闭了甚至关机了……那么我们还可以用 git reflog 来找回 id ,它记录了完整的 log :

b87e2c5 HEAD@{0}: reset: moving to b87e2c5fd623591a510a4873aecdc43793de392e
f5c7b7b HEAD@{1}: reset: moving to HEAD^
b87e2c5 HEAD@{2}: commit: add a new line.
f5c7b7b HEAD@{3}: commit (initial): create a readme file

E. 工作区和暂存区

我们看到的目录 /home/xing/MEQE_local ,实际上就是工作区 working directory 。

我们最开始提到的 .git 隐藏目录,不属于工作区,而是版本库 repository 。
其中最重要的就是暂存区 stage (index) ,还有 Git 自动为我们创建的第一个分支 master ,以及指向 master 的指针 HEAD 。

IMAGE 1

如图,这就明白 add 和 commit 的工作原理了。
第一步 add ,实际上是把文件从工作区添加到暂存区;
第二步 commit ,实际上是把文件从暂存区提交到当前分支。

分支和 HEAD 后面讲。

所以我们说:我们可以连续 add 很多文件到暂存区,最后一次性 commit 到分支里。

实验:我们把 readme.txt 的第二行删掉,再创建一个 LICENSE.txt 文件。然后再查看状态:

On branch master
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.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    LICENSE.txt

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

系统检测到: readme.txt 改动了但没有 commit ,而工作区里的 LICENSE.txt 甚至还没有 add 到暂存区,因此没有被“跟踪”。
换句话说,暂存区里的 readme.txt 就是被跟踪的。

我们分别对这两个文件都执行 add 以后,状态显示:

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

    new file:   LICENSE.txt
    modified:   readme.txt

图就不看了,两个文件现在都在暂存区里。

然后 git commit -m "commit 2 files." ,搞定!此时暂存区就空了。

什么叫 working tree clean ?即提交时,没有对工作区进行新的改动。

F. 管理修改的概念

现在的 readme.txt 只有一行。

假设我们:

  • readme.txt 中增加一行;
  • 仅仅 add 没有 commit
  • 又增加一行,然后无任何操作;
  • commit

可以猜到,尽管真实的文件已经修改了两回,但只有第一次修改通过 add 放入到暂存区,第二次修改没有被放入暂存区。
因此如果查看状态,会显示:

On branch master
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.txt

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

这就是管理修改,而不是管理文件的例子。

我们可以通过 git diff HEAD -- readme.txt 命令,查看 工作区文件 和 版本库中的最新版本 的区别:

diff --git a/readme.txt b/readme.txt
index 80cc1f9..785e827 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,3 @@
 Git is free software.
 Hello
+Hello again

G. 撤销修改

如果我们错误修改了工作区文件,并且 commit 了,那么撤销修改只能用版本回退的方法。

如果我们错误修改了工作区文件,但还没有 add ,那么最直接的办法就是:手动删除错误变动。

除此之外,我们可以用 git checkout -- readme.txt 操作,撤销工作区文件的变动。

有两种情况:

  1. 在错误修改前,该文件最后一次修改已经被 commit 了。
    那么撤销后,工作区文件将会和版本库最新文件一致。
  2. 在错误修改前,该文件最后一次修改未被 commit (仅被 add)。
    那么撤销后,工作区文件将和暂存区文件一致。

总之就是撤销一步工作区的修改,无论上一次修改是否 commit 到了分支。

-- 的作用是:保持在当前分支。否则会切换到另一分支。后面讲。

如果我们错误修改了工作区文件,并且已经 add 了。此时需要两步。

第一步,用 reset 操作撤销 add 更改:

git reset HEAD readme.txt

这里的 HEAD 声明:回退到暂存区历史最新版本。

第二步,撤销工作区文件操作。方法上面说过了,就是 git checkout -- readme.txt

最后,如果我们不仅 commit 了,而且还推送到远程版本库了,那就凉了。后面讲。

H. 删除文件

假设我们在文件管理器中把 LICENSE.txt 删除了: rm LICENSE.txt
此时查看状态会显示 deleted 。

如果确认不是误删,我们可以从版本库中删除对应文件: git rm LICENSE.txt ,注意也要 commit

当然了,addcommit 也可以,因为删除也是一种对文件的修改。

如果是误删,那么此时由于还没有 add ,因此我们可以用 checkout 撤销误操作。
本质上是用版本库的最新文件,替换工作区版本。

3. Git 的杀手锏一:远程仓库

如果只是本地版本控制系统(或集中式),那么 Git 相较于 SVN 没有任何优势。
但作为分布式管理系统, Git 有众多优势。远程仓库是第一个杀手锏。

Git 的同一个仓库,可以部署到不同的机器上。

对个人玩家(比如我)而言,我们不会在一台机器的多个硬盘上进行同步,而是在个人电脑和远程服务器上进行同步。
我们可以自行搭建一台运行 Git 的服务器,但更多时候,我们会借助 GitHub 等 Git 仓库托管服务平台

注意,本地 Git 仓库和 GitHub 仓库之间的传输是通过 SSH 加密的,因此需要以下准备:

  1. 创建 SSH Key。参考教程
    在命令行中输入: ssh-keygen -t rsa -C "youremail@example.com",无需设置密码。
    在用户主目录可以找到 .ssh 目录,里面有公钥 id_rsa.pub 和 私钥 id_rsa
  2. 登录远程仓库,填入 id_rsa.pub 文件的内容。

原因是,远程仓库需要知道是本人提交的推送,而 Git 支持 SSH 协议。

如果我们有很多电脑,那就把这些设备的公钥都设置好。

A. 添加远程仓库

在网站上操作。

假设我们现在有一个文件夹: /home/xing/Desktop/MFQE_code ,并将其设置为 Git 可管理的本地仓库

我们将其和网站上的 MFQE 仓库关联。在当前目录下运行:

git remote add origin https://gitee.com/XINGRYAN/MFQE.git

后面的地址别搞错了,否则可能会关联到别人的远程库,但由于公钥不在其列表中,因此无法推上去。

添加后,远程仓库名就是 origin ,这是 Git 默认的叫法,可改,但一看到 origin 就知道是远程库。

B. 推送上去

我们写一个 README.md ,将其推送到远程库上。

推送前,我们应该先 add commit

然后执行:

git push -u origin master

# Counting objects: 7, done.
# Delta compression using up to 8 threads.
# Compressing objects: 100% (3/3), done.
# Writing objects: 100% (7/7), 593 bytes | 0 bytes/s, done.
# Total 7 (delta 0), reused 0 (delta 0)
# remote: Powered by Gitee.com
# To https://gitee.com/XINGRYAN/MFQE.git
#  * [new branch]      master -> master
# Branch master set up to track remote branch master from origin.

意思是:将当前分支 master 推送到远程。
由于远程库是空的,因此第一次推送时,我们加上 -u 参数,不仅完成了推送,而且还将本地和远程的 master 分支关联起来,在以后的推送和拉取时可以简化命令。

实际上 Git 支持 多种协议,包括 SSH 和 https 。上面用到的正是 https 。

C. 从远程库克隆

如果我们本地什么都没有,希望从远程库上克隆下来一个库,那么我们可以这么操作。

首先,假设有一个库名为 gitskills ,属于 michaelliao 的,里面只有一个 README.md 。那么我们执行:

git clone git@github.com:michaelliao/gitskills.git

# Cloning into 'gitskills'...
# remote: Counting objects: 3, done.
# remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
# Receiving objects: 100% (3/3), done.

此时在本地的 gitskills 目录下,就有了一个完全相同的库,含 README.md

学习笔记 | Git

原文:https://www.cnblogs.com/RyanXing/p/10460447.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!