Git 基础———创建仓库及提交更新
Contents
Git 基础———创建仓库及提交更新
创建仓库
有两种创建仓库的方法:
-
将没有进行版本控制的本地目录转换为 Git 仓库;
-
从其他服务器克隆一个已存在的 Git 仓库。
我们就可以从 GitHub 上使用 ‘git clone’ 这个命令克隆一个 Git 仓库。
在没有进行版本控制的本地目录初始化仓库
进入到你想进行版本控制的目录,使用以下命令:
1 | git init |
这个命令会创建一个名为 .git
的子目录,这个子目录含有你初始化的 Git 仓库中所有的必须文件,这些文件是 Git 仓库的骨干。
使用 git add
命令来指定所需的文件进行跟踪及初始化提交:
1 | git add *.c |
git add
将文件提交到暂存区。
关于
LICENSE
开源许可证,可以看看这篇文章:如何选择开源许可证? - 阮一峰的网络日志 (ruanyifeng.com)
git commit
将暂存区中的所有内容提交到当前分支(创建版本库时 git 自动创建一个 master 分支)
-m
是提交信息,查看别人或者自己的历史记录的时候,这个东西是挺重要的。以下是 Git 的标准注解:
1
2
3 第1行:提交修改内容的摘要
第2行:空行
第3行以后:修改的理由
克隆现有的仓库
git clone
命令:
1 | git clone <url> |
比如克隆我的一个项目:
1 | git clone https://github.com/Xunop/kakaBot |
这会在当前目录下创建一个叫 kakaBot 的目录,并在这个目录下初始化一个 .git
文件夹, 从远程仓库拉取下所有数据放入 .git
文件夹,然后从中读取最新版本的文件的拷贝。可以在后面添加自定义本地仓库的名字。
举例
我会将命令及执行结果放在一起。中间会夹带 Git 命令的介绍。
初始化仓库
1 | git init |
查看当前文件状态
使用 git status
查看当前文件状态:
1 | git status |
git status
命令输出还可以使用缩短,使用-s
或者-short
选项可以缩短状态命令的输出。
1
2 git status -s
A README新添加的未跟踪文件前面有
??
标记,新添加到暂存区中的文件前面有A
标记,修改过的文件前面有M
标记。 输出中有两栏,左栏指明了暂存区的状态,右栏指明了工作区的状态。
这说明我们现在的工作目录相当干净。换句话说,所有已跟踪文件在上次提交后都未被更改过。这个命令还显示了当前分支,我当前分支名是 main
。好像是之前我学长帮我改成 main
的。
创建一个 README
文件。如果之前不存在这个文件,使用 git status
命令会有看到一个未跟踪文件:
1 | echo 'README' > README |
Untracked files
表示为跟踪文件清单。未跟踪的文件意味着 Git 在之前的快照(提交)中没有这些文件;Git 不会自动将之纳入跟踪范围。
跟踪新文件
使用命令 git add
开始跟踪一个文件。 所以,要跟踪 README
文件,运行:
1 | git add README |
此时再运行 git status
命令,会看到 README
文件已被跟踪,并处于暂存状态:
1 | git status |
只要在 Changes to be committed
这行下面的,就说明是已暂存状态。如果我们现在提交,那么这个文件就会从暂存区提交到我们的分支 main
中。 git add
命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。
暂存已修改的文件
我们创建一个文件 test.md
,然后将它加入到暂存区中。之后我们修改这个文件再查看状态:
1 | git status |
这个文件出现在 Changes not staged for commit
这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。 要暂存这次更新,需要运行 git add
命令。 这是个多功能命令:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等。运行 git add
将这个文件加入到暂存区中,再次查看状态:
1 | git status |
如果此时我们再次修改 test.md
文件,然后查看状态:
1 | git status |
test.md
同时出现在暂存区跟非暂存区,如果我们此时提交的话,提交的是在暂存区中的文件,因为我们最后一次修改的文件还没加入到暂存区。
查看已暂存和未暂存的修改
这个的话如果使用可视化倒是很清晰,直接看命令行还是有点累。
使用 git diff
命令可以通过文件补丁的格式更加具体地显示哪些行发生了改变。
使用 git diff --staged
命令或者 git diff --cached
查看已暂存的将要添加到下次提交里的内容。 这条命令将比对已暂存文件与最后一次提交的文件差异:
1 | git diff --staged |
我么可以使用
git difftool
调用一些可视化软件帮助我们查看修改,如果你没有下载的话会提示你下载的。使用
git difftool --tool-help
命令来看你的系统支持哪些 Git Diff 插件。
提交更新
中间插了这么多步骤,这里总算可以提交了。
1 | git commit |
这样会启动你选择的文本编辑器来输入提交说明。我是用 vscode。
启动的编辑器是通过 Shell 的环境变量
EDITOR
指定的,一般为 vim 或 emacs。 可以使用git config --global core.editor
命令设置喜欢的编辑器。直接改文件~/.gitconfig
这个文件中有编辑器配置设置。我在前面的文章中也有提到--global
选项更改文件是在这个目录下。
编写了提交说明直接退出编辑器就行了。打开编辑器会显示更新内容,不过这些更新内容是用 #
注释了的,不会提交。
使用 -m
选项提交:
1 | git commit -m 'first commit' |
此时我们使用
git log
查看 git 日志:
1
2
3
4 git log
commit 5abccae89d89d1bdb52a724d7bc40da0dd685c2e (HEAD -> main)
Author: Xunop <1234567@qq.com>
Date: Mon Aug 22 23:13:55 2022 +0800出现了我们的提交记录
跳过暂存区
每次提交都需要将文件加入到暂存区,文件一多就有点繁琐,我们可以使用选项 -a
这样 Git 会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过 git add
步骤:
1 | git commit -a -m 'add df' |
不过需注意,有时这个选项会将不需要的文件添加到提交中。
移除文件
其实 Git 也提示了我们,在之前的命令输出中出现过这种提示:
1 | (use "git rm --cached <file>..." to unstage) |
还有这种:
1 | (use "git add <file>..." to update what will be committed) |
又捡到一个命令 git restore <file>...
这个命令有点好玩,可以恢复已删除文件。
如果你删除一个已经加入到暂存区的文件,不过还没有暂存这个更改,也就是出现我说的简单地从工作目录中手工删除文件的情况,我们可以使用
git restore
来恢复这个文件:
1
2
3
4
5
6
7
8
9
10
11 rm file1.txt
ll
total 2
-rw-r--r-- 1 xun 197121 32 8月 22 23:24 df
-rw-r--r-- 1 xun 197121 7 8月 22 22:38 README
git restore file1.txt
ll
total 3
-rw-r--r-- 1 xun 197121 32 8月 22 23:24 df
-rw-r--r-- 1 xun 197121 9 8月 22 23:59 file1.txt
-rw-r--r-- 1 xun 197121 7 8月 22 22:38 README如果我们删除了一个已经加入到暂存区的文件,并且还暂存了这个更改,我们使用这个命令就会报错:
1
2
3
4 rm file1.txt
git add .
git restore file1.txt
error: pathspec 'file1.txt' did not match any file(s) known to git关于
git add .
是添加当前目录下的所有文件到暂存区。这样就不能恢复了吗?如果你之前已经提交过这个文件的话还能恢复的,我们使用
git restore --staged --worktree <filename>
这个命令:
1 git restore --staged --worktree file1.txt
--staged
参数告诉 Git 从 HEAD 恢复索引(暂存区)中的文件,--worktree
告诉 Git 恢复工作树(工作区)。这个文件恢复的只是我们之前提交的,如果我们对这个文件进行过更改且没有提交到当前分支,那么那些修改是没有恢复的。
还有更极限的情况就要使用
git checkout
命令了。可以去了解一下。这篇文章有记载的:Recovering Deleted Files in GitHub - Rewind。
要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用 git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
如果只是简单地从工作目录中手工删除文件(我这里删除 test.md
文件),运行 git status
时就会在 “Changes not staged for commit” 部分(也就是 未暂存清单)看到:
1 | git status |
如果这时候提交还是显示这个的,出现这个的原因是我们删除(修改)了 test.md
文件但是尚未添加到暂存区。前面当我们修改了一个文件但是没有加入到暂存区也是显示这个。
如果我们使用 git rm test.md
就不会显示这个:
1 | git rm test.md |
如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项 -f
。这是防止误删,因为 Git 并不能恢复这些数据。
有个问题就是我们只是想把这个文件从 Git 仓库中删除而不是在我们工作目录(也就是我们本地)中也删除,我们使用 git rm
命令时会把我们本地的这个文件也删除。有时候我们就遇到忘记把一些文件添加到 .gitignore
文件里(.gitignore
文件一旦确定就不能再改,它的介绍在后面),然后被添加到暂存区里 的情况(写这篇文章的时候刚好遇到这个问题,一个不能上传的配置文件差点给我上传了)。这时我们使用 --cached
选项就很有用了:
1 | git rm --cached README |
使用这个不会从我们本地删除,而是让 Git 不再跟踪。
git rm
命令后面可以列出文件或者目录的名字,也可以使用glob
模式。比如:
1 git rm log/\*.log注意到星号
*
之前的反斜杠\
, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除log/
目录下扩展名为.log
的所有文件。 类似的比如:
1 git rm \*~该命令会删除所有名字以
~
结尾的文件。
移动文件
既然如此,当你看到 Git 的 mv
命令时一定会困惑不已。 要在 Git 中对文件改名,可以这么做:
1 | git mv fileNem newFileName |
1 | git mv README.md README |
其实,运行 git mv
就相当于运行了下面三条命令:
1 | mv README.md README |
运行 git mv
就相当于运行了下面三条命令:
1 | mv README.md README |
忽略文件
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore
的文件,列出要忽略的文件的模式。 来看一个实际的 .gitignore
例子:
1 | cat .gitignore |
第一行告诉 Git 忽略所有以 .o
或 .a
结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的。 第二行告诉 Git 忽略所有名字以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。 此外,你可能还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。 要养成一开始就为你的新仓库设置好 .gitignore
文件的习惯,以免将来误提交这类无用的文件。
文件 .gitignore
的格式规范如下:
- 所有空行或者以
#
开头的行都会被 Git 忽略。 - 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中。
- 匹配模式可以以(
/
)开头防止递归。 - 匹配模式可以以(
/
)结尾指定目录。 - 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(
!
)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。 星号(*
)匹配零个或多个任意字符;[abc]
匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c); 问号(?
)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9]
表示匹配所有 0 到 9 的数字)。 使用两个星号(**
)表示匹配任意中间目录,比如 a/**/z
可以匹配 a/z
、 a/b/z
或 a/b/c/z
等。
我们再看一个 .gitignore
文件的例子:
1 | # 忽略所有的 .a 文件 |
我一般使用 IDEA 自带的😎,不过 Github 有一个项目是包括了很多种情况的.gitignore
文件列表,看这里:github/gitignore: A collection of useful .gitignore templates。我写这个东西写得比较少,也就加几个配置文件,IDEA 生成的足够使用了。
参考文章及文档:
Recovering Deleted Files in GitHub - Rewind
Git - Book (git-scm.com)
如何选择开源许可证? - 阮一峰的网络日志 (ruanyifeng.com)
Author: xun
Link: http://blog.fooo.in/2022/08/23/Git/Git-Basic-03/
License:
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。