⭐获取 Git 仓库
获取 Git 仓库有两种方式:
- 将未进行版本控制的本地目录转换为 Git 仓库。
- 从其他服务器克隆一个已存在的 Git 仓库。
在已存在目录中初始化 Git 仓库
- 进入目标目录
-
- 在 Linux 上:
$ cd /home/user/my_project
- 在 macOS 上:
$ cd /Users/user/my_project
- 在 Linux 上:
$ cd /c/user/my_project
- 在 Linux 上:
- 执行初始化:
$ git init
克隆现有的 Git 仓库
- 克隆仓库命令:
$ git clone https://github.comlibgit2/libgit2
- 克隆并修改名称命令:
$ git clone https://github.comlibgit2/libgit2/mylibgit
⭐记录每次更新到仓库
工作目录下的每一个文件只有两种状态:已跟踪 或未跟踪
- 已跟踪:被纳入版本控制的的文件,在上一次快照中有它们的记录。已跟踪的文件的状态可能为:未修改、已修改、已暂存。即已经知道的文件。
- 未跟踪:除已跟踪以外的文件。
检查当前文件状态------git status
可以用 git status 命令查看哪些文件处于什么状态。
-
克隆仓库后使用:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean -
新建 Git 仓库后使用:
跟踪新文件------git add
-
使用命令
git add
开始跟踪一个文件。 所以,要跟踪README
文件,运行:$ git add README
-
此时再运行
git status
命令,会看到README
文件已被跟踪,并处于暂存状态:$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)new file: README
-
只要在
Changes to be committed
这行下面的,就说明是已暂存状态。 如果此时提交,那么该文件在你运行git add
时的版本将被留存在后续的历史记录中。 -
git add
命令使用文件或目录的路径作为参数;如果参数是目录的路径,该命令将递归地跟踪该目录下的所有文件。
暂存已修改的文件------git add
git add
是个多功能命令:应理解为"精确地将内容添加到下一次提交中"而不是"将一个文件添加到新项目中"。
- 开始跟踪新文件
- 把已跟踪的文件放到暂存区
- 合并时把有冲突的文件标记为已解决状态
git commit
时,提交的文件是最后一次运行git add
时的版本,而不是git commit
时的版本。所以一个文件可能即在 暂存区 又在 非暂存区。
状态简览------git status -s
Git 有一个选项可以帮你缩短状态命令的输出,这样可以以简洁的方式查看更改。 如果你使用 git status -s 命令或 git status --short 命令,你将得到一种格式更为紧凑的输出。
$ git status -s
M README
MM Rakefile
A lib/git.rb
M lib/simplegit.rb
?? LICENSE.txt
- 左列:暂存区的状态,右列:工作区的状态。
??
:新添加且未追踪的文件。A
(Added):新添加到暂存区的文件。M
(Modified):修改过的文件。
- M README
-
- 左列为空,说明
README
文件在暂存区没有更改。 - 右列是
M
,说明文件在工作区中被修改,但尚未暂存。
- 左列为空,说明
- MM Rakefile
-
- 左列是
M
,说明Rakefile
文件的某些更改已经被添加到暂存区。 - 右列是
M
,说明文件在工作区中又有了新的更改,但这些更改尚未被添加到暂存区。
- 左列是
- A lib/git.rb
-
- 左列是
A
,说明lib/git.rb
是一个新文件,已被添加到暂存区。 - 右列为空,说明该文件在工作区没有未暂存的更改。
- 左列是
- ?? LICENSE.txt
-
- 双问号
??
表示LICENSE.txt
是一个新文件,尚未被 Git 跟踪(未被添加到暂存区)。
- 双问号
忽略文件------.gitignore
一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。 通常都是些自动生成的文件,比如日志文件,或者编译过程中创建的临时文件等。 在这种情况下,我们可以创建一个名为 .gitignore
的文件,列出要忽略的文件的模式。 来看一个实际的 .gitignore
例子:
$ cat .gitignore
*.[oa]
*~
第一行告诉 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
文件的例子:
# 忽略所有的 .a 文件
*.a
# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a
# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO
# 忽略任何目录下名为 build 的文件夹
build/
# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt
# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf
|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Tip | GitHub 有一个十分详细的针对数十种项目及语言的 .gitignore
文件列表, 你可以在 GitHub - github/gitignore: A collection of useful .gitignore templates找到它。 |
|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Note | 在最简单的情况下,一个仓库可能只根目录下有一个 .gitignore
文件,它递归地应用到整个仓库中。 然而,子目录下也可以有额外的 .gitignore
文件。子目录中的 .gitignore
文件中的规则只作用于它所在的目录中。 (Linux 内核的源码库拥有 206 个 .gitignore
文件。) 多个 .gitignore
文件的具体细节超出了本书的范围,更多详情见 man gitignore
。 |
查看已暂存和未暂存的修改------git diff
- 通常可能会用它来回答这两个问题:
- 当前做的哪些更新尚未暂存?
-
- 要查看尚未暂存的文件更新了哪些部分,不加参数直接输入
git diff
- 注意,git diff 本身只显示尚未暂存的改动,而不是自上次提交以来所做的所有改动。 所以有时候你一下子暂存了所有更新过的文件,运行
git diff
后却什么也没有,就是这个原因。
- 要查看尚未暂存的文件更新了哪些部分,不加参数直接输入
- 有哪些更新已暂存并准备好下次提交?
-
- 若要查看已暂存的将要添加到下次提交里的内容,可以用
git diff --staged
命令。 这条命令将比对已暂存文件与最后一次提交的文件差异:
- 若要查看已暂存的将要添加到下次提交里的内容,可以用
- 虽然
git status
已经通过在相应栏下列出文件名的方式回答了这个问题,但git diff
能通过文件补丁的格式更加具体地显示哪些行发生了改变。
|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Note | Git Diff 的插件版本 在本书中,我们使用 git diff
来分析文件差异。 但是你也可以使用图形化的工具或外部 diff 工具来比较差异。 可以使用 git difftool
命令来调用 emerge 或 vimdiff 等软件(包括商业软件)输出 diff 的分析结果。 使用 git difftool --tool-help
命令来看你的系统支持哪些 Git Diff 插件。 |
提交更新------git commit
-
现在的暂存区已经准备就绪,可以提交了。 在此之前,请务必确认还有什么已修改或新建的文件还没有
git add
过, 否则提交的时候不会记录这些尚未暂存的变化。 这些已修改但未暂存的文件只会保留在本地磁盘。 所以,每次准备提交前,先用git status
看下,你所需要的文件是不是都已暂存起来了, 然后再运行提交命令git commit
:$ git commit
-
这样会启动你选择的文本编辑器来输入提交说明。
|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Note | 启动的编辑器是通过 Shell 的环境变量 EDITOR
指定的,一般为 vim 或 emacs。 当然也可以按照 起步 介绍的方式, 使用 git config --global core.editor
命令设置你喜欢的编辑器。 |
-
编辑器会显示类似下面的文本信息(本例选用 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
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
new file: README
modified: CONTRIBUTING.md
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C -
可以看到,默认的提交消息包含最后一次运行
git status
的输出,放在注释行里,另外开头还有一个空行,供你输入提交说明。 你完全可以去掉这些注释行,不过留着也没关系,多少能帮你回想起这次更新的内容有哪些。
|----------|-----------------------------------------------------------------------|
| Note | 更详细的内容修改提示可以用 -v
选项查看,这会将你所作的更改的 diff 输出呈现在编辑器中,以便让你知道本次提交具体作出哪些修改。 |
- 退出编辑器时,Git 会丢弃注释行,用你输入的提交说明生成一次提交。
-
另外,你也可以在
commit
命令后添加-m
(message) 选项,将提交信息与命令放在同一行,如下所示:$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
2 files changed, 2 insertions(+)
create mode 100644 README
- 可以看到,提交后它会告诉你,当前是在哪个分支(
master
)提交的,本次提交的完整 SHA-1 校验和是什么(463dc4f
),以及在本次提交中,有多少文件修订过,多少行添加和删改过。 - 请记住,提交时记录的是放在暂存区域的快照。 任何还未暂存文件的仍然保持已修改状态,可以在下次提交时纳入版本管理。 每一次运行提交操作,都是对你项目作一次快照,以后可以回到这个状态,或者进行比较。
跳过使用暂存区域------git commit -a
-
Git 提供了一个跳过使用暂存区域的方式, 只要在提交的时候,给
git commit
加上-a
选项,Git 就会自动把所有已经跟踪过的文件暂存起来一并提交,从而跳过git add
步骤:$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
1 file changed, 5 insertions(+), 0 deletions(-) -
这很方便,但是要小心,有时这个选项会将不需要的文件添加到提交中。
移除文件------git rm
- 要从 Git 中移除某个文件,就必须要从已跟踪文件清单中移除(确切地说,是从暂存区域移除),然后提交。 可以用
git rm
命令完成此项工作,并连带从工作目录中删除指定的文件,这样以后就不会出现在未跟踪文件清单中了。
-
如果只是简单地从工作目录中手工删除文件,运行
git status
时就会在 "Changes not staged for commit" 部分(也就是 未暂存清单)看到:$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)deleted: PROJECTS.md
no changes added to commit (use "git add" and/or "git commit -a")
-
然后再运行
git rm
记录此次移除文件的操作:$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)deleted: PROJECTS.md
-
下一次提交时,该文件就不再纳入版本管理了。 如果要删除之前修改过或已经放到暂存区的文件,则必须使用强制删除选项
-f
(译注:即 force 的首字母)。 这是一种安全特性,用于防止误删尚未添加到快照的数据,这样的数据不能被 Git 恢复。
-
另外一种情况是,我们想把文件从 Git 仓库中删除(亦即从暂存区域移除),但仍然希望保留在当前工作目录中。 换句话说,你想让文件保留在磁盘,但是并不想让 Git 继续跟踪。 当你忘记添加
.gitignore
文件,不小心把一个很大的日志文件或一堆.a
这样的编译生成文件添加到暂存区时,这一做法尤其有用。 为达到这一目的,使用--cached
选项:$ git rm --cached README
-
git rm
命令后面可以列出文件或者目录的名字,也可以使用glob
模式。比如:$ git rm log/*.log
-
注意到星号
*
之前的反斜杠\
, 因为 Git 有它自己的文件模式扩展匹配方式,所以我们不用 shell 来帮忙展开。 此命令删除log/
目录下扩展名为.log
的所有文件。 类似的比如:$ git rm *~
-
该命令会删除所有名字以
~
结尾的文件。
移动文件------git mv <file_from> <file_to>
-
当你看到 Git 的
mv
命令时一定会困惑不已。 要在 Git 中对文件改名,可以这么做:$ git mv file_from file_to
-
它会恰如预期般正常工作。 实际上,即便此时查看状态信息,也会明白无误地看到关于重命名操作的说明:
$ git mv README.md README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)renamed: README.md -> README
-
其实,运行
git mv
就相当于运行了下面三条命令: -
如此分开操作,Git 也会意识到这是一次重命名,所以不管何种方式结果都一样。 两者唯一的区别在于,
git mv
是一条命令而非三条命令,直接使用git mv
方便得多。 不过在使用其他工具重命名文件时,记得在提交前git rm
删除旧文件名,再git add
添加新文件名。
查看提交历史------git log
不传入任何参数的默认情况下,git log
会按时间先后顺序列出所有的提交,最近的更新排在最上面。 正如你所看到的,这个命令会列出每个提交的 SHA-1 校验和、作者的名字和电子邮件地址、提交时间以及提交说明。
常用的选项
- 常用选项表:
|-------------------|-----------------------------------------------------------------------|
| 选项 | 说明 |
| -p
| 按补丁格式显示每个提交引入的差异。 |
| --stat
| 显示每次提交的文件修改统计信息。 |
| --shortstat
| 只显示 --stat 中最后的行数修改添加移除统计。 |
| --name-only
| 仅在提交信息后显示已修改的文件清单。 |
| --name-status
| 显示新增、修改、删除的文件清单。 |
| --abbrev-commit
| 仅显示 SHA-1 校验和所有 40 个字符中的前几个字符。 |
| --relative-date
| 使用较短的相对时间而不是完整格式显示日期(比如"2 weeks ago")。 |
| --graph
| 在日志旁以 ASCII 图形显示分支与合并历史。 |
| --pretty
| 使用其他格式显示历史提交信息。可用的选项包括 oneline、short、full、fuller 和 format(用来定义自己的格式)。 |
| --oneline
| --pretty=oneline --abbrev-commit
合用的简写。 |
-p
(patch):比较有用的选项是-p
或--patch
,它会显示每次提交所引入的差异(按 补丁 的格式输出)。
-
- 也可以限制显示的日志条目数量,例如使用
-2
选项来只显示最近的两次提交 - 该选项除了显示基本信息之外,还附带了每次提交的变化。 当进行代码审查,或者快速浏览某个搭档的提交所带来的变化的时候,这个参数就非常有用了。
- 也可以限制显示的日志条目数量,例如使用
--stat
(statistic):提供每次提交的简略统计信息
-
--stat
选项在每次提交的下面列出所有被修改过的文件、有多少文件被修改了以及被修改过的文件的哪些行被移除或是添加了。 在每次提交的最后还有一个总结。
--pretty
:可以使用不同于默认格式的方式展示提交历史。
-
oneline
:会将每个提交放在一行显示,在浏览大量的提交时非常有用。short
,full
,fuller
:它们展示信息的格式基本一致,但是详尽程度不一。format
:可以定制记录的显示格式。 这样的输出对后期提取分析格外有用------因为你知道输出的格式不会随着 Git 的更新而发生改变
-
-
git log --pretty=format
常用的选项表:
-
|--------|-----------------------------|
| 选项 | 说明 |
| %H
| 提交的完整哈希值 |
| %h
| 提交的简写哈希值 |
| %T
| 树的完整哈希值 |
| %t
| 树的简写哈希值 |
| %P
| 父提交的完整哈希值 |
| %p
| 父提交的简写哈希值 |
| %an
| 作者名字 |
| %ae
| 作者的电子邮件地址 |
| %ad
| 作者修订日期(可以用 --date=选项 来定制格式) |
| %ar
| 作者修订日期,按多久以前的方式显示 |
| %cn
| 提交者的名字 |
| %ce
| 提交者的电子邮件地址 |
| %cd
| 提交日期 |
| %cr
| 提交日期(距今多长时间) |
| %s
| 提交说明 |
--graph
:添加了一些 ASCII 字符串来形象地展示你的分支、合并历史。
限制输出选项
|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 选项 | 说明 |
| -<n>
| 仅显示最近的 n 条提交。 |
| --since
, --after
| 仅显示指定时间之后的提交。(可以是类似 "2008-01-15"
的具体的某一天,也可以是类似 "2 years 1 day 3 minutes ago"
的相对日期。) |
| --until
, --before
| 仅显示指定时间之前的提交。 |
| --author
| 仅显示作者匹配指定字符串的提交。 |
| --committer
| 仅显示提交者匹配指定字符串的提交。 |
| --grep
| 仅显示提交说明中包含指定字符串的提交。 |
| -S
| 仅显示添加或删除内容匹配指定字符串的提交。 非常有用的过滤器是 -S
(俗称"pickaxe"选项,取"用鹤嘴锄在土里捡石头"之意), 它接受一个字符串参数,并且只会显示那些添加或删除了该字符串的提交。 假设你想找出添加或删除了对某一个特定函数的引用的提交,可以调用:$ git log -S function_name
|
| --<path>
| 如果只关心某些文件或者目录的历史提交,可以在 git log 选项的最后指定它们的路径。 因为是放在最后位置上的选项,所以用两个短划线(--)隔开之前的选项和后面限定的路径名。 |
|----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| Note | 你可以指定多个 --author
和 --grep
搜索条件,这样会只输出匹配 任意 --author
模式和 任意 --grep
模式的提交。然而,如果你添加了 --all-match
选项, 则只会输出匹配 所有 --grep
模式的提交。 |
实例
来看一个实际的例子,如果要在 Git 源码库中查看 Junio Hamano 在 2008 年 10 月其间, 除了合并提交之外的哪一个提交修改了测试文件,可以使用下面的命令:
$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \
--before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch
在近 40000 条提交中,上面的输出仅列出了符合条件的 6 条记录。
|---------|---------------------------------------------------------------------------------------------------------|
| Tip | 隐藏合并提交 按照你代码仓库的工作流程,记录中可能有为数不少的合并提交,它们所包含的信息通常并不多。 为了避免显示的合并提交弄乱历史记录,可以为 log
加上 --no-merges
选项。 |
撤销操作
重新提交------git commit --amend
- 有时候我们提交完了才发现漏掉了几个文件没有添加,或者提交信息写错了。 此时,可以运行带有
--amend
选项的提交命令来重新提交。 - 这个命令会将暂存区中的文件提交。 如果自上次提交以来你还未做任何修改(例如,在上次提交后马上执行了此命令), 那么快照会保持不变,而你所修改的只是提交信息。
- 最终你只会有一个提交------第二次提交将代替第一次提交的结果。
✍️:
- 当你在修补最后的提交时,与其说是修复旧提交,倒不如说是完全用一个 新的提交 替换旧的提交, 理解这一点非常重要。从效果上来说,就像是旧有的提交从未存在过一样,它并不会出现在仓库的历史中。
- 修补提交最明显的价值是可以稍微改进你最后的提交,而不会让"啊,忘了添加一个文件"或者 "小修补,修正笔误"这种提交信息弄乱你的仓库历史。
取消暂存的文件------git reset HEAD <file>
- 例如,你已经修改了两个文件并且想要将它们作为两次独立的修改提交, 但是却意外地输入
git add *
暂存了它们两个。用来只取消暂存两个中的一个。
✍️:
git reset
确实是个危险的命令,如果加上了--hard
选项则更是如此。 然而在上述场景中,工作目录中的文件尚未修改,因此相对安全一些。
撤销对文件的修改------git checkout --<file>
- 不想保留对某文件的修改。
✍️:
- 请务必记得
git checkout --- <file>
是一个危险的命令。 你对那个文件在本地的任何修改都会消失------Git 会用最近提交的版本覆盖掉它。 除非你确实清楚不想要对那个文件的本地修改了,否则请不要使用这个命令。
总结
在 Git 中任何 已提交 的东西几乎总是可以恢复的。 甚至那些被删除的分支中的提交或使用 --amend
选项覆盖的提交也可以恢复 (阅读 数据恢复 了解数据恢复)。 然而,任何你未提交的东西丢失后很可能再也找不到了。
远程仓库的使用
为了能在任意 Git 项目上协作,你需要知道如何管理自己的远程仓库。 远程仓库是指托管在因特网或其他网络中的你的项目的版本库。 你可以有好几个远程仓库,通常有些仓库对你只读,有些则可以读写。 与他人协作涉及管理远程仓库以及根据需要推送或拉取数据。 管理远程仓库包括了解如何添加远程仓库、移除无效的远程仓库、管理不同的远程分支并定义它们是否被跟踪等等。
✍️远程仓库可以在你的本地主机上:
你完全可以在一个"远程"仓库上工作,而实际上它在你本地的主机上。 词语"远程"未必表示仓库在网络或互联网上的其它位置,而只是表示它在别处。 在这样的远程仓库上工作,仍然需要和其它远程仓库上一样的标准推送、拉取和抓取操作。
查看远程仓库------git remote
- 列出你指定的每一个远程服务器的简写。
- 如果你已经克隆了自己的仓库,那么至少应该能看到 origin ------这是 Git 给你克隆的仓库服务器的默认名字。
- 指定选项
-v
,会显示需要读写远程仓库使用的 Git 保存的简写与其对应的 URL。
添加远程仓库------git remote add <shortname> <url>
- 运行
git remote add <shortname> <url>
添加一个新的远程 Git 仓库,同时指定一个方便使用的简写 - 如果指定了简写,以后可以用<shortname>代替整个 URL。如:
git fetch <shortname>
。
从远程仓库抓取与拉取------git fetch <remote> <branch>
, git pull <remote> <branch>
fetch
: 访问远程仓库,从中拉取所有你还没有的数据。 执行完成后,你将会拥有那个远程仓库中所有分支的引用,可以随时合并或查看。pull
:
-
- 如果你的当前分支设置了跟踪远程分支, 那么可以用
git pull
命令来自动抓取后合并该远程分支到当前分支。 - 默认情况下,
git clone
命令会自动设置本地 master 分支跟踪克隆的远程仓库的master
分支(或其它名字的默认分支)。 运行git pull
通常会从最初克隆的服务器上抓取数据并自动尝试合并到当前所在的分支。
- 如果你的当前分支设置了跟踪远程分支, 那么可以用
推送到远程仓库------git push <remote> <branch>
- 当你想要将
master
分支推送到origin
服务器时(再次说明,克隆时通常会自动帮你设置好那两个名字), 那么运行这个命令就可以将你所做的备份到服务器: - 只有当你有所克隆服务器的写入权限,并且之前没有人推送过时,这条命令才能生效。 当你和其他人在同一时间克隆,他们先推送到上游然后你再推送到上游,你的推送就会毫无疑问地被拒绝。 你必须先抓取他们的工作并将其合并进你的工作后才能推送。
查看某个远程仓库------git show <remote>
-
它会列出远程仓库的 URL 与跟踪分支的信息。 这些信息非常有用,它告诉你正处于
master
分支,并且如果运行git pull
, 就会抓取所有的远程引用,然后将远程master
分支合并到本地master
分支。 它也会列出拉取到的所有远程引用。 -
这个命令列出了当你在特定的分支上执行
git push
会自动地推送到哪一个远程分支。 它也同样地列出了哪些远程分支不在你的本地,哪些远程分支已经从服务器上移除了, 还有当你执行git pull
时哪些本地分支可以与它跟踪的远程分支自动合并。 -
示例:
$ git remote show origin
- remote origin
URL: https://github.com/my-org/complex-project
Fetch URL: https://github.com/my-org/complex-project
Push URL: https://github.com/my-org/complex-project
HEAD branch: master
Remote branches:
master tracked
dev-branch tracked
markdown-strip tracked
issue-43 new (next fetch will store in remotes/origin)
issue-45 new (next fetch will store in remotes/origin)
refs/remotes/origin/issue-11 stale (use 'git remote prune' to remove)
Local branches configured for 'git pull':
dev-branch merges with remote dev-branch
master merges with remote master
Local refs configured for 'git push':
dev-branch pushes to dev-branch (up to date)
markdown-strip pushes to markdown-strip (up to date)
master pushes to master (up to date)
- remote origin
远程仓库的重命名与移除------git remote rename
, git remote remove
-
git remote rename
:修改一个远程仓库的简写名。 例如,想要将pb
重命名为paul
,可以用git remote rename
这样做:$ git remote rename pb paul
$ git remote
origin
paul -
- 值得注意的是这同样也会修改你所有远程跟踪的分支名字。 那些过去引用
pb/master
的现在会引用paul/master
。
- 值得注意的是这同样也会修改你所有远程跟踪的分支名字。 那些过去引用
git remote remove
:移除一个远程仓库------你已经从服务器上搬走了或不再想使用某一个特定的镜像了, 又或者某一个贡献者不再贡献了。
-
- 一旦你使用这种方式删除了一个远程仓库,那么所有和这个远程仓库相关的远程跟踪分支以及配置信息也会一起被删除。
打标签------git tag
1. 列出标签
- 使用
git tag
查看所有标签。 - 可以使用
git tag -l "v1.8.5*"
按模式过滤标签。
2. 创建标签
- 附注标签 :使用
git tag -a <tagname> -m "message"
创建,包含打标签者信息、时间、信息等。 - 轻量标签 :使用
git tag <tagname>
创建,仅是指向某提交的引用,没有附加信息。
3. 后期打标签
- 通过
git tag -a <tagname> <commit-hash>
为过去的提交打标签。
4. 共享标签
- 使用
git push origin <tagname>
推送标签。 - 使用
git push origin --tags
推送所有标签。
5. 删除标签
- 本地删除标签:
git tag -d <tagname>
。 - 从远程删除标签:
git push origin :refs/tags/<tagname>
或git push origin --delete <tagname>
。
6. 检出标签
- 使用
git checkout <tagname>
检出标签,进入"分离头指针"状态。
Git 别名
Git 别名可以帮助简化命令,减少输入长度,使 Git 操作更加高效。你可以通过配置别名,将常用的长命令缩短为更直观的命令。
常见的 Git 别名配置示例
1. 基本命令简化
git config --global alias.co checkout
将git checkout
简化为git co
。git config --global alias.br branch
将git branch
简化为git br
。git config --global alias.ci commit
将git commit
简化为git ci
。git config --global alias.st status
将git status
简化为git st
。
2. 自定义实用别名
-
取消暂存文件
git config --global alias.unstage 'reset HEAD --'
使用 git unstage fileA
撤销暂存,等价于 git reset HEAD -- fileA
。
-
查看最后一次提交
git config --global alias.last 'log -1 HEAD'
使用 git last
查看最后一次提交记录。
3. 外部命令别名
-
运行外部工具
git config --global alias.visual '!gitk'
使用 git visual
打开 gitk
图形界面工具。
其他提示
- Git 别名本质上是将别名替换为实际命令,完全可以根据自己的习惯定义。
- 外部命令需要在别名前加上
!
,比如运行第三方工具或脚本。