整体介绍:
在学习了Git相关的概念之后,我们正式开始学习如何使用Git
这篇文章主要分为两个部分:
- 基础使用
- 进阶使用
中篇负责讲述基础的使用liux
基础使用
Git诞生:安装
Git 支持在 Windows、MacOS、Linux、Unix
MacOS安装:
MacOS有一个强大的包管理器:HomeBrew
包管理器简单的认为是一个应用商店,你可以下载,安装,删除,看应用相关信息,升级应用(后面我会专门写一篇包管理器的文章)
它能够简化很多操作,尤其是对于程序员需要的一些工具的安装:
- Python解释器
- GCC
- Git
- JDK
- …
如果是在搜索引擎搜索的话,可能需要安装,并且配置环境变量,相对来说麻烦很多,所以会使用包管理器相当重要
所以,Git 也能够 通过HomeBrew安装
- 首先安装HomeBrew,打开终端,输入:
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装结束就可以使用了(详细不在这里展开,后面会写一篇专门介绍HomeBrew的文章)
- 然后在终端中,输入命令行:
brew install git
- 安装结束,输入命令验证一下:
git --version
- 打印出版本信息既是安装成功
Windows安装:
Windows我使用不多,上面也有包管理器(Scoop、Chocolatey),但是我感觉不好用,我们就用传统的方法来进行Git的下载吧
直接点击这里,在官方网站下载,安装完成后在,菜单里面找到Git 打开Git Bash,就能跳出一个类似于这样的窗口(我身边没win的机器,只有在网上找的图):
最后也是对git进行验证
GNU/Linux安装:
使用包管理器安装:
Linux因为有太多的发行版本,不同的比如Debian、CentOS里面的默认的包管理器就不同,常见的有:
- yum
- apt-get
所以对应安装的方法就是:
yum install git
apt-get install git
玩Linux的应该都懂~
安装好Git之后开始下一步
Git启动:初始化
git的启动首先需要创建仓库,或者说版本库,什么意思呢,就是在指定文件夹下面,输入命令,让它拥有git的能力,能在里面进行版本控制
如果你不会一些基础命令,建议你先学习一些基本的命令,不过这里面用的最多的是 cd 这个命令,就是到指定路径下面,就是你想创建仓库的地方
到了指定路径下面,输入:
git init
你就让你的文件夹变成了一个版本库了
So easy~ 这样Git初始化这个步骤就完成了,我们继续下一步
Git穿越时空:版本控制
工作区、暂存区、版本库、分支:
Git 工作中,有两个区域:
工作区
版本库:
又分为:
- 暂存区
- 分支
- …
我们来看看四者之间的区别。
工作区 就是你初始化之后,把文件夹变成版本库,这个文件夹,就是工作区
版本库 就是工作区里面的一个隐藏文件夹.git,版本控制就是通过它实现
暂存区 是版本库的一部分
分支 是版本库的一部分,创建版本库默认的分支就是master
补充一个概念: 目录树 ,目录树是指由容器和对象构成的层次结构。树的叶子、节点往往是对象,树的非叶子节点是容器
图片这些元素的解释:
在版本库中标记为 “index” 的区域是暂存区(也叫stage),在 ".git/index"文件中 ,是一个目录树
标记为 “master” 的是 master 分支所代表的目录树。在 “.git/refs/master” 文件中
图中我们可以看出此时 “HEAD” 实际是指向 master 分支的一个指针,在.git/HEAD 文件中,它记录着目前指向的是什么分支
图中的 objects 标识的区域为 Git 的对象库,实际位于 “.git/objects” 目录下,里面包含了创建的各种对象及内容。
基本工作流
当对工作区修改(或新增)的文件执行 “git add” 命令时,工作区的文件被存入暂存区:
- 暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,缓存区的文件被提交的当前的分支(master)
- master 指向的目录树被提交时暂存区的目录树所替换。
可能上面这部分有点枯燥,主要是想一定的说明git的原理,不过适可而止,毕竟原理解释不是这篇文章主要目的,主要是为了使用git。
基本操作
Git 的工作就是创建和保存你项目的快照及与之后的快照进行对比。本章将对有关创建与提交你的项目快照的命令作介绍。
获取与创建项目命令
git init
用 git init 在目录中创建新的 Git 仓库。 你可以在任何时候、任何目录中这么做,完全是本地化的。
在目录中执行 git init,就可以创建一个 Git 仓库了。比如我们创建 test 项目:
$ mkdir test
$ cd test/
$ git init
Initialized empty Git repository in /Users/liuxunzhuo/top/liuxunzhuo/.git/
# 在 /top/liuxunzhuo/.git/ 目录初始化空 Git 仓库完毕。
现在你可以看到在你的项目中生成了 .git 这个子目录。 这就是你的 Git 仓库了,所有有关你的此项目的快照数据都存放在这里。
ls -a
. .. .git
git clone
使用 git clone 拷贝一个云端的Git 仓库到本地,让自己能够查看该项目,或者进行修改。
如果你需要与他人合作一个项目,或者想要复制一个项目,看看代码,你就可以克隆那个项目。 执行命令:
git clone [url]
[url] 为你想要复制的项目,就可以了。
例如我们克隆 Github 上的项目:
$ git clone git@github.com:Xunzhuo/SpringBoot-in-Action.git
Cloning into 'SpringBoot-in-Action'...
remote: Counting objects: 13, done.
remote: Total 13 (delta 0), reused 0 (delta 0), pack-reused 13
Receiving objects: 100% (13/13), done.
Resolving deltas: 100% (2/2), done.
Checking connectivity... done.
克隆完成后,在当前目录下会生成一个SpringBoot-in-Action 目录:
$ cd SpringBoot-in-Action/
$ ls
README src
上述操作将复制该项目的全部记录。
$ ls -a
. .. .git README Rakefile lib
$ cd .git
$ ls
HEAD description info packed-refs
branches hooks logs refs
config index objects
默认情况下,Git 会按照你提供的 URL 所指示的项目的名称创建你的本地项目目录。 通常就是该 URL 最后一个 / 之后的项目名称。如果你想要一个不一样的名字, 你可以在该命令后加上你想要的名称。
Git 的工作就是创建和保存你的项目的快照及与之后的快照进行对比。本章将对有关创建与提交你的项目的快照的命令作介绍。
git add
git add 命令可将该文件添加到缓存区,如我们添加以下两个文件:
$ touch README
$ touch hello.py
$ ls
README hello.py
$ git status -s
?? README
?? hello.py
$
git status 命令用于查看项目的当前状态。
接下来我们执行 git add 命令来添加文件:
$ git add README hello.py
现在我们再执行 git status,就可以看到这两个文件已经加上去了。
$ git status -s
A README
A hello.py
$
新项目中,添加所有文件很普遍,我们可以使用 git add . 命令来添加当前项目的所有文件。
现在我们修改 README 文件:
$ vim README
在 README 添加以下内容:然后保存退出。
再执行一下 git status:
$ git status -s
AM README
A hello.py
“AM” 状态的意思是,这个文件在我们将它添加到缓存之后又有改动。改动后我们再执行 git add 命令将其添加到缓存中:
$ git add .
$ git status -s
A README
A hello.py
当你要将你的修改包含在即将提交的快照里的时候,需要执行 git add。
git status
git status 以查看在你上次提交之后是否有修改。
我演示该命令的时候加了 -s 参数,以获得简短的结果输出。如果没加该参数会详细输出内容:
$ git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: README
new file: hello.py
git diff
执行 git diff 来查看执行 git status 的结果的详细信息。
git diff 命令显示已写入缓存与已修改但尚未写入缓存的改动的区别。git diff 有两个主要的应用场景。
- 尚未缓存的改动:git diff
- 查看已缓存的改动: git diff --cached
- 查看已缓存的与未缓存的所有改动:git diff HEAD
- 显示摘要而非整个 diff:git diff --stat
在 hello.py 文件中输入以下内容:
print("hello world")
git status 显示你上次提交更新后的更改或者写入缓存的改动, 而 git diff 一行一行地显示这些改动具体是啥。
接下来我们来查看下 git diff --cached 的执行效果:
$ git add hello.py
$ git status -s
A README
A hello.py
$ git diff --cached
diff --git a/README b/README
new file mode 100644
index 0000000..e69de29
diff --git a/hello.py b/hello.py
new file mode 100644
index 0000000..8cde782
--- /dev/null
+++ b/hello.py
@@ -0,0 +1 @@
+print("hello world")
git commit
使用 git add 命令将想要快照的内容写入缓存区, 而执行 git commit 将缓存区内容添加到仓库中。
Git 为你的每一个提交都记录你的名字与电子邮箱地址,所以第一步需要配置用户名和邮箱地址。
$ git config --global user.name 'xunzhuo'
$ git config --global user.email 981242367@qq.com
接下来我们写入缓存,并提交对 hello.py 的所有改动。在首个例子中,我们使用 -m 选项以在命令行中提供提交注释。
$ git commit -m "init"
[master(根提交) 39aeab6] init
2 files changed, 1 insertion(+)
create mode 100644 README
create mode 100644 hello.py
现在我们已经记录了快照。如果我们再执行 git status:
$ git status
位于分支 master
无文件要提交,干净的工作区
以上输出说明我们在最近一次提交之后,没有做任何改动,是一个"working directory clean:干净的工作目录"。
如果你没有设置 -m 选项,Git 会尝试为你打开一个编辑器以填写提交信息。 如果 Git 在你对它的配置中找不到相关信息,默认会打开 vim。屏幕会像这样:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: hello.py
#
~
~
".git/COMMIT_EDITMSG" 9L, 257C
如果你觉得 git add 提交缓存的流程太过繁琐,Git 也允许你用 -a 选项跳过这一步。命令格式如下(注意,只适合修改,如果新创建了文件,还是得先add,来修改缓存区的文件树):
git commit -a
git commit -am
我们先修改 hello.py 文件为以下内容:
for i in range(100):
print("hello world")
再执行以下命令:
git commit -am '修改 hello.py 文件'
[master 5f2df9d] 修改 hello.py 文件
1 file changed, 2 insertions(+), 1 deletion(-)
git rm
如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 Changes not staged for commit 的提示。
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除,然后提交。可以用以下命令完成此项工作
git rm <file>
如果删除之前修改过并且已经放到暂存区域的话,则必须要用强制删除选项 -f
git rm -f <file>
如果把文件从暂存区域移除,但仍然希望保留在当前工作目录中,换句话说,仅是从跟踪清单中删除,使用 –cached 选项即可
git rm --cached <file>
如我们删除 hello.py文件:
$ git rm hello.py
rm 'hello.py'
$ ls
README
不从工作区中删除文件:
$ git rm --cached README
rm 'README'
$ ls
README
可以递归删除,即如果后面跟的是一个目录做为参数,则会递归删除整个目录中的所有子目录和文件:
git rm –r *
进入某个目录中,执行此语句,会删除该目录下的所有文件和子目录。
git mv
git mv 命令用于移动或重命名一个文件、目录、软连接。
我们先把刚移除的 README 添加回来:
$ git add README
然后对其重名:
$ git mv README README.md
$ ls
README.md
git log
在使用 Git 提交了若干更新之后,又或者克隆了某个项目,想回顾下提交历史,我们可以使用 git log 命令查看。
针对我们前一章节的操作,使用 git log 命令列出历史提交记录如下:
$ git log
commit d5e9fc2c811e0ca2b2d28506ef7dc14171a207d9 (HEAD -> master)
Merge: c68142b 7774248
Author: xunzhuo <test@xunzhuo.com>
Date: Fri May 3 15:55:58 2019 +0800
Merge branch 'change_site'
commit c68142b562c260c3071754623b08e2657b4c6d5b
Author: xunzhuo <test@xunzhuo.com>
Date: Fri May 3 15:52:12 2019 +0800
修改代码
commit 777424832e714cf65d3be79b50a4717aea51ab69 (change_site)
Author: xunzhuo <test@xunzhuo.com>
Date: Fri May 3 15:49:26 2019 +0800
changed the xunzhuo.py
commit c1501a244676ff55e7cccac1ecac0e18cbf6cb00
Author: xunzhuo <test@xunzhuo.com>
Date: Fri May 3 15:35:32 2019 +0800
我们可以用 --oneline 选项来查看历史记录的简洁的版本。
$ git log --oneline
$ git log --oneline
d5e9fc2 (HEAD -> master) Merge branch 'change_site'
c68142b 修改代码
7774248 (change_site) changed the xunzhuo.py
c1501a2 removed test.txt、add xunzhuo.py
3e92c19 add test.txt
3b58100 第一次版本提交
这告诉我们的是,此项目的开发历史。
我们还可以用 --graph 选项,查看历史中什么时候出现了分支、合并。以下为相同的命令,开启了拓扑图选项:
* d5e9fc2 (HEAD -> master) Merge branch 'change_site'
|\
| * 7774248 (change_site) changed the xunzhuo.py
* | c68142b 修改代码
|/
* c1501a2 removed test.txt、add xunzhuo.py
* 3e92c19 add test.txt
* 3b58100 第一次版本提交
现在我们可以更清楚明了地看到何时工作分叉、又何时归并。
你也可以用 –reverse 参数来逆向显示所有日志。
$ git log --reverse --oneline
3b58100 第一次版本提交
3e92c19 add test.txt
c1501a2 removed test.txt、add xunzhuo.py
7774248 (change_site) changed the xunzhuo.py
c68142b 修改代码
d5e9fc2 (HEAD -> master) Merge branch 'change_site'
如果只想查找指定用户的提交日志可以使用命令:git log --author , 例如,比方说我们要找 Git 源码中 Linus 提交的部分:
$ git log --author=Linus --oneline -5
81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
3bb7256 make "index-pack" a built-in
377d027 make "git pack-redundant" a built-in
b532581 make "git unpack-file" a built-in
112dd51 make "mktag" a built-in
如果你要指定日期,可以执行几个选项:–since 和 --before,但是你也可以用 --until 和 --after。
例如,如果我要看 Git 项目中三周前且在四月十八日之后的所有提交,我可以执行这个(我还用了 --no-merges 选项以隐藏合并提交):
$ git log --oneline --before={
3.weeks.ago} --after={
2010-04-18} --no-merges
5469e2d Git 1.7.1-rc2
d43427d Documentation/remote-helpers: Fix typos and improve language
272a36b Fixup: Second argument may be any arbitrary string
b6c8d2d Documentation/remote-helpers: Add invocation section
5ce4f4e Documentation/urls: Rewrite to accomodate transport::address
00b84e9 Documentation/remote-helpers: Rewrite description
03aa87e Documentation: Describe other situations where -z affects git diff
77bc694 rebase-interactive: silence warning when no commits rewritten
636db2c t3301: add tests to use --format="%N"
git放弃修改&放弃增加文件
本地修改了一堆文件(并没有使用git add到暂存区),想放弃修改。
- 单个文件/文件夹:
$ git checkout -- filename
- 所有文件/文件夹:
$ git checkout .
本地新增了一堆文件(并没有git add到暂存区),想放弃修改。
- 单个文件/文件夹:
$ rm filename / rm dir -rf
- 所有文件/文件夹:
$ git clean -xdf
// 删除新增的文件,如果文件已经已经git add到暂存区,并不会删除!
本地修改/新增了一堆文件,已经git add到暂存区,想放弃修改。
- 单个文件/文件夹:
$ git reset HEAD filename
- 所有文件/文件夹:
$ git reset HEAD
.
本地通过git add & git commit 之后,想要撤销此次commit
$ git reset commit_id
这个id是你想要回到的那个节点,可以通过git log查看,可以只选前6位
// 撤销之后,你所做的已经commit的修改还在工作区!
$ git reset --hard commit_id
这个id是你想要回到的那个节点,可以通过git log查看,可以只选前6位
// 撤销之后,你所做的已经commit的修改将会清除,仍在工作区/暂存区的代码也将会清除!
好的,基础部分到这里结束了,接下来进行最后的进阶学习!
坚持就是胜利~