proc_git 第二章 git基础

本文详细介绍Git的基本操作,包括初始化仓库、文件的跟踪与取消跟踪、暂存与提交更新、查看历史记录、撤销操作以及远程仓库的管理等。适用于初学者快速掌握Git的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        概述:本章主要讲解了git的,停止与开始跟踪某个文件;暂存或者提交某些更新;如何过滤某些不想跟踪的文件,如何撤销小的错误,浏览项目的更新历史,查看两次更改之间的差异,如何与远程数据库进行互动。


1.取得项目的git仓库


1.1从当前目录进行初始化

        如果我们需要备份自己的代码,或者在异地进行办公而想对同一份代码进行编辑,此时往往选用这种模式。执行

$git init

        初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录,但我们还没有开始跟踪管理项目中的任何一个文件。

        将一些文件加入其中并提交:

$vim a.c b.c README

$git add *.c README

$git commit -m "the first commit"


1.2从现有项目clone

$ git clone git://github.com/schacon/grit.git


2.检查仓库中文件的状态


使用git status命令:

$ git status
# On branch master
nothing to commit (working directory clean)

_________________________

现在让我们用 vim 编辑一个新文件 README,保存退出后运行 git status 会看到该文件出现在未跟踪文件列表中:
$ vim README
$ git status

# On branch master
# Untracked files:
#
(use "git add <file>..." to include in what will be committed)
#
# README
nothing added to commit but untracked files present (use "git add" to track)


2.1跟踪新文件

接着上面,我们想要跟踪README,需要输入:

$git add README

检查:

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


2.2暂存已修改的文件

在我们修改下之前已跟踪过的文件 benchmarks.rb,然后再次运行 status 命令,会看到这样的状态报告:
$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# new file:
README
#
# Changed but not updated:
#
(use "git add <file>..." to update what will be committed)
#
# modified:
benchmarks.rb
#
文件 benchmarks.rb 出现在 “Changed but not updated” 这行下面,说明已跟踪文件的内容发生了变化,但还没有放到暂存区。要暂存这次更新,需要运行 git add 命令(这是个多功能命令,根据目标文件的状态不同,此命令的效果也不同:可以用它开始跟踪新文件,或者把已跟踪的文件放到暂存区,还能用于合并时把有冲突的文件标记为已解决状态等)。

现在让我们运行 git add 将 benchmarks.rb 放到暂存区,然后再看看 git status的输出:
$ git add benchmarks.rb
$ git status

# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# new file: README
# modified: benchmarks.rb
16
Scott Chacon Pro Git


2.2节 记录每次更新到仓库

#
现在两个文件都已暂存,下次提交时就会一并记录到仓库。假设此时,你想要在 bench-marks.rb 里再加条注释,重新编辑存盘后,准备好提交。不过且慢,再运行 git status看看:
$ vim benchmarks.rb
$ git status

# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# new file: README
# modified: benchmarks.rb
#
# Changed but not updated:
#
(use "git add <file>..." to update what will be committed)
#
# modified:
benchmarks.rb
#
见鬼!benchmarks.rb 文件出现了两次!一次算未暂存,一次算已暂存,这怎么可能呢?好吧,实际上 Git 只不过暂存了你运行 git add 命令时的版本,如果现在提交,那么提交的是添加注释前的版本,而非当前工作目录中的版本。所以,运行了 git add 之后又作了修订的文件,需要重新运行 git add 把最新版本重新暂存起来:
$ git add benchmarks.rb
$ git status

# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# new file: README
# modified: benchmarks.rb


2.3忽略某些文件

一般我们总会有些文件无需纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常都是些自动生成的文件,像是日志或者编译过程中创建的等等。我们可以创建一个名为.gitignore 的文件,列出要忽略的文件模式,来看一个简单的例子:
$ cat .gitignore
*.[oa]
*~
Scott Chacon Pro Git
第一行告诉 Git 忽略所有以 .o 或 .a 结尾的文件。一般这类对象文件和存档文件都是编译过程中出现的,我们用不着跟踪它们的版本。第二行告诉 Git 忽略所有以波浪符(~)结尾的文件,许多文本编辑软件(比如 Emacs)都用这样的文件名保存副本。此外,你可能
还需要忽略 log,tmp 或者 pid 目录,以及自动生成的文档等等。要养成一开始就设置好.gitignore 文件的习惯,以免将来误提交这类无用的文件。


文件 .gitignore 的格式规范如下:
• 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
• 可以使用标准的 glob 模式匹配。
• 匹配模式最后跟反斜杠(/)说明要忽略的是目录。
• 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号(!)取反。
所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(*)匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到9 的数字)。


我们再看一个 .gitignore 文件的例子:
# 此为注释 – 将被 Git 忽略
*.a # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

 

2.4查看已经暂存和未暂存的更新

git status仅仅查看的是哪些文件发生了变化,比较粗糙;如果想以补丁的形似查看具体更新的信息,可以使用git diff

其中默认的git diff对比是当前工作目录和缓存区,git diff --cached对比暂存区和已提交的不同。


2.5提交已经暂存的更新

git commit 以互动方式让用户输入commit信息,其中第一行是标题,空行,然后接着解释;或者用git commit -m将所有信息包涵在一行之中。


2.6跳过使用暂存区域:git commit -a 


2.7移除文件:git rm

git rm:git-rm - Remove files from the working tree and from the index

目标一:不再想跟踪某个文件,将它从当前工作目录和stage状态下移除

方法:git rm

结果:如果file同时存在在stage和wd之下,那么git rm将会失败,提示错误:

error: 'hyk' has changes staged in the index
(use --cached to keep the file, or -f to force removal)

 说明;如果一个文件已经改变了stage状态,那么是不能用git rm直接删除的


混淆:如果直接rm,那么显示为“deleted but not updated”,因为此时它仍然处在跟踪状态

 

目标二:把文件暂存区域中删除,但是保留在当前工作目录下

方法:$git rm --cached file


目标二:把文件暂存区域中删除,而且保留在当前工作目录下

方法:$git rm --f file




2.8移动文件

 git-mv - Move or rename a file, a directory, or a symlink


目标:将文件README.txt 更名为README,stage和wd之下的文件同时改变

方法:git mv README.txt README

或者:mv README.txt README; git rm README.txt; git add README


3查看提交历史


 git log

查看修改的详细信息:git log -p

详细显示最近的n次修改:git log -p -n

仅仅统计修改的行数:git log --stat

图形化显示:git log --graph


3.1限制输出长度

1)需求:时间限制,最近两周的修改 

方法:$git log --since=2.weeks

拓展:选项 说明
-(n) 仅显示最近的 n 条提交
--since, --after 仅显示指定时间之后的提交。
--until, --before 仅显示指定时间之前的提交。
--author 仅显示指定作者相关的提交。
--committer 仅显示指定提交者相关的提交。


3.2使用图形化工具查询提交历史

gitk工具

用法:在当前目录和分支下输入: $gitk


4.撤销操作


4.1修改最后一次提交

情景:提交完毕,发现漏掉几个文件,或者提交信息写错了

方法:$git commit --amend

说明:此命令将使用当前的暂存区域快照提交。如果刚才提交完没有作任何改动,直接运行此命
令的话,相当于有机会重新编辑提交说明,而所提交的文件快照和之前的一样。

情景2:如果刚才提交时忘了暂存某些修改,可以先补上暂存操作,然后再运行 --amend 提交:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

上面的三条命令最终得到一个提交,第二个提交命令修正了第一个的提交内容。

解释:git commit --amend 相当于用当前暂存区的文件来修改上一次的提交。总之,这个撤销操作是撤销从暂存区到本地仓库的这一步


4.2取消已经暂存的操作

情景一:现在有两个文件,已经被修改而且都提交到暂存区域,如果我们用git commit,那么这两个文件将同时被提交。现在,我想分两次提交,应该怎办法?

$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
# modified: README.txt
# modified: benchmarks.rb

方法:

$ git reset HEAD benchmarks.rb
benchmarks.rb: locally modified
$ git status
# On branch master
# Changes to be committed:
#
(use "git reset HEAD <file>..." to unstage)
#
#
modified:
README.txt
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
#
#

说明:也就是说,git reset将当前暂存区的某些文件撤销到工作目录之中


4.3取消对文件的修改

情景一:觉得刚才对 benchmarks.rb 的修改完全没有必要,该如何取消修改,回到之前的状态(也就是修改之前的版本)呢?

方法:$ git checkout -- benchmarks.rb
$ git status

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

注意事项:git checkout --benchmarks.rb是用当前已经提交的文件重写工作目录下的文件,有很大的危险性。因为git可以撤销任何已经提交的操作,但是没有提交过的却会丢失。


5.远程仓库


管理远程仓库的工作,包括添加远程库,移除废弃的远程库,管理各式远程库分支,定义是否跟踪这些分支,等等。本节我们将详细讨论远程库的管理和使用。


5.1查看远程仓库

要查看当前配置有哪些远程仓库,可以用 git remote 命令

需求一:查看远程仓库地址

方法:git remote -v


5.2添加远程仓库

方法:运行 git remote add [shortname] [url]:


5.3从远程仓库抓取数据

方法:git fetch

说明:如果是克隆了一个仓库,此命令会自动将远程仓库归于 origin 名下。所以,git fetchorigin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。有一点很重要,需要记住,fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支,只有当你确实准备好了,才能手工合并。

注意:如果设置了某个分支用于跟踪某个远端仓库的分支(参见下节及第三章的内容),可以使用 git pull 命令自动抓取数据下来,然后将远端分支自动合并到本地仓库中当前分支。在日常工作中我们经常这么用,既快且好。实际上,默认情况下 git clone 命令本质上就是自动创建了本地的 master 分支用于跟踪远程仓库中的 master 分支(假设远程仓库确实有master 分支)。所以一般我们运行 git pull,目的都是要从原始克隆的远端仓库中抓取数据后,合并到工作目录中当前分支。


5.4推送数据到远程仓库

方法:git push [remote-name] [branch-name]

注意:只有在所克隆的服务器上有写权限,或者同一时刻没有其他人在推数据,这条命令才会如期完成任务。如果在你推数据前,已经有其他人推送了若干更新,那你的推送操作就会被驳回。你必须先把他们的更新抓取到本地,并到自己的项目中,然后才可以再次推送。有关推送数据到远程仓库的详细内容见第三章。


5.5查看远程仓库信息

方法:git remote show [remote-name] 
示例:
$ git remote show origin
* remote origin
URL: git@github.com:defunkt/github.git
Remote branch merged with 'git pull' while on branch issues
issues
Remote branch merged with 'git pull' while on branch master
master
New remote branches (next fetch will store in remotes/origin)
caching
Stale tracking branches (use 'git remote prune')
libwalker
walker2
Tracked remote branches
acl
apiv2
dashboard2
issues
master
postgres
Local branch pushed with 'git push'
master:master
它告诉我们,运行 git push 时缺省推送的分支是什么(译注:最后两行)。它还显示了有哪些远端分支还没有同步到本地(译注:第六行的 caching 分支),哪些已同步到本地的远端分支在远端服务器上已被删除(译注:Stale tracking branches 下面的两个分支),以及运行 git pull 时将自动合并哪些分支(译注:前四行中列出的 issues 和master 分支)。

5.6远程仓库的删除和重命名

方法:
$ git remote rename pb paul
$ git remote rm paul

6.标签

本节我们一起来学习如何列出所有可用的标签,如何新建标签,以及各种不同类型标签之间的差别。


6.1显示标签

需求一:显示所有标签
方法:git tag
需求二:显示特定标签
方法:git tag -l "v1.4.2"

6.2新建标签

什么是标签:Git 使用的标签有两种类型:轻量级的(lightweight)和含附注的(annotated)。轻量级标签就像是个不会变化的分支,实际上它就是个指向特定提交对象的引用。而含附注标签,实际上是存储在仓库中的一个独立对象,它有自身的校验和信息,包含着标签的名字,电子邮件地址和日期,以及标签说明,标签本身也允许使用 GNU Privacy Guard (GPG) 来
签署或验证。一般我们都建议使用含附注型的标签,以便保留相关信息;当然,如果只是临时性加注标签,或者不需要旁注额外信息,用轻量级标签也没问题。
1)新建含有附注的标签
方法: git tag -a v1.4 -m “my ersion 1.4”
需求:查看相应标签的版本信息:
方法:git  show tagname
2)签署标签:tag -s
方法:git tag -s v1.5 -m “my signed 1.5 tag”
3)轻量级标签
方法:git tag v1.4(不用-a -s等等)

6.3验证标签

方法:git tag -v v1.4

6.4后期加注标签

方法:打标签的时候,加上对应对象的校验和(或者前几位字符)
具体:$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'exper

$ git tag -a v1.2 9fceb02

6.5分享标签

默认情况下,git push 并不会把标签传送到远端服务器上,只有通过显式命令才能分享标签到远端仓库。其命令格式如同推送分支,运行 git push origin [tagname] 即可:
如果要一次推送所有(本地新增的)标签上去,可以使用 --tags 选项:


7.技巧和窍门


7.1自动补全

如果你用的是 Bash shell,可以试试看 Git 提供的自动完成脚本。下载 Git 的源代码,进入 contrib/completion 目录,会看到一个 git-completion.bash 文件。将此文件复制到你自己的用户主目录中

7.2 Git 命令别名

Git 并不会推断你输入的几个字符将会是哪条命令,不过如果想偷懒,少敲几个命令的字符,可以用 git config 为命令设置别名。来看看下面的例子:
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
现在,如果要输入 git commit 只需键入 git ci 即可。而随着 Git 使用的深入,会有很多经常要用到的命令,遇到这种情况,不妨建个别名提高效率。使用这种技术还可以创造出新的命令,比方说取消暂存文件时的输入比较繁琐,可以自己设置一下:
$ git config --global alias.unstage 'reset HEAD --'
这样一来,下面的两条命令完全等同:
$ git unstage fileA
$ git reset HEAD fileA
显然,使用别名的方式看起来更清楚。另外,我们还经常设置 last 命令:
$ git config --global alias.last 'log -1 HEAD'
然后要看最后一次的提交信息,就变得简单多了:
$ git last
commit 66938dae3329c7aebe598c2246a8e6af90d04646
Author: Josh Goebel <dreamer3@example.com>
Date:
Tue Aug 26 19:48:51 2008 +0800

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值