Git是一款免费、开源的分布式版本控制系统,它用于敏捷高效地处理任何大小的项目。学习Git指令对于版本控制、团队协作以及项目管理至关重要。

Git 初始化与配置是 Git 版本控制系统使用的第一步,它们在本地计算机上创建一个新的 Git 仓库并设置基本的用户信息。
Git 初始化是通过 git init 命令完成的。这个命令会在当前目录下创建一个新的 .git 目录(如果该目录不存在的话),并初始化仓库的所有必需文件和结构。.git 目录是 Git 用来存储仓库的元数据(如配置信息、对象数据库、引用等)的地方,它是 Git 仓库的核心。
git init 执行上述命令后,当前目录及其子目录中的文件就可以被 Git 跟踪和管理了。不过,需要注意的是,新创建的仓库默认不包含任何文件;需要通过 git add 命令将文件添加到暂存区,并通过 git commit 命令将暂存区的更改提交到仓库中。
Git 配置是通过 git config 命令完成的。这个命令允许我们设置 Git 的各种选项和变量,以控制 Git 的行为。配置可以是全局的(对所有仓库生效),也可以是仓库级别的(仅对当前仓库生效)。配置信息存储在三个不同的地方:
.git/config 文件中。.gitconfig 文件中(Windows 系统下可能是 %USERPROFILE%\.gitconfig)。/etc/gitconfig(Linux)或 C:\Program Files\Git\etc\gitconfig(Windows)中。全局配置是针对当前用户所有仓库的设置。它存储在用户主目录下的 .gitconfig 文件中(Windows 系统下可能是 %USERPROFILE%\.gitconfig)。
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"这两个命令分别设置了全局的用户名和邮箱地址。这些信息会被 Git 用于所有的提交(commit),以标识是谁做了这次更改。使用 --global 选项表示这些配置将应用于当前用户的所有 Git 仓库。
仓库级别配置仅针对当前仓库有效。它存储在仓库目录下的 .git/config 文件中。
--global 选项来设置仓库级别的配置。但是,对于用户名和邮箱这样的常用配置,通常建议设置为全局的,以避免在每个仓库中都进行相同的设置。git config user.name "[name]"
git config user.email "[emailaddress]" 如果不使用 --global 选项,则这些配置仅对当前仓库有效。这在需要为不同的仓库使用不同的身份信息时非常有用。
要查看当前仓库的配置(包括全局配置),可以使用 git config --list 命令。如果只想查看全局配置,可以添加 --global 选项;如果只想查看仓库级别的配置,可以进入到仓库目录下,然后直接运行 git config --list(因为默认情况下它会显示当前仓库的配置)。
git config --list
# 或者
git config --global --listGit 初始化与配置是 Git 版本控制系统使用的基础。通过
git init命令,可以在本地计算机上创建一个新的 Git 仓库。通过git config命令,可以设置 Git 的各种选项和变量,以控制 Git 的行为。这些配置可以是全局的,也可以是仓库级别的,根据需要进行设置。
git clone 是 Git 中用于从远程仓库复制项目(包括其所有历史记录)到本地计算机上的命令。这个命令是 Git 工作流程中非常基础且常用的一个步骤,它允许开发者在本地环境中对代码进行修改、测试等操作,然后再将更改推送到远程仓库。
git clone [url] [directory][url]:远程仓库的 URL,这是必须的参数。URL 可以是 HTTP(s)、SSH 或 Git 协议格式的。[directory]:可选参数,指定克隆仓库的本地目录名。如果不指定,Git 会默认使用远程仓库的名称(通常是去掉 URL 中最后一部分的路径或主机名后的部分)。git/git 仓库,可以这样做:git clone https://github.com/git/git.git这会在当前目录下创建一个名为 git 的新目录,并将远程仓库的内容克隆到这个目录中。
my-git,可以这样做:git clone https://github.com/git/git.git my-git这会在当前目录下创建一个名为 my-git 的新目录,并将远程仓库的内容克隆到这个目录中。
如果只对仓库的当前状态感兴趣,而不关心它的完整历史记录,可以使用 --depth 选项来执行浅克隆。浅克隆只会下载最近的几个提交历史。
git clone --depth 1 https://github.com/username/repository.git在这个例子中,--depth 1 表示只下载最新的提交及其父提交,从而节省带宽和时间。
默认情况下,git clone 会克隆远程仓库的 main(或 master,取决于仓库的配置和 Git 版本)分支。如果想要克隆特定的分支,可以使用 --branch 或 -b 选项,但请注意,这并不会自动切换到该分支;它只会确保该分支的历史被下载到本地。要切换到该分支,还需要执行 git checkout(或 git switch,在较新版本的 Git 中)。
git clone -b <branch-name> --single-branch <repository-url>
# 然后切换到该分支(Git 2.23+ 可以使用 git switch)
git checkout <branch-name>
# 或者
git switch <branch-name>但请注意,--single-branch 选项是必要的,因为它告诉 Git 只克隆指定的分支,而不是整个仓库的所有分支。
在 Git 中,提交代码是一个重要的过程,它涉及到将更改从工作目录(即正在编辑的目录)移动到 Git 的暂存区(Stage/Index),然后再从暂存区提交到本地仓库的历史记录中。以下是关于 git add 和 git commit 命令的详细解释,以及如何使用它们来提交代码和修改提交信息。
3.1. git addgit add 命令用于将文件内容从工作目录添加到暂存区(Stage/Index)。在 Git 中,任何新创建或修改的文件都不会自动成为版本控制的一部分,直到显式地告诉 Git 你想要跟踪这些更改。
git add [file1] [file2] ...这个命令会将指定的文件添加到暂存区。可以一次添加一个或多个文件。
git add .使用点(.)作为参数,Git 会将当前目录及其子目录下所有修改过的(未跟踪的或已修改但尚未提交的)文件添加到暂存区。
3.2. git commitgit commit 命令用于将暂存区的更改提交到本地仓库。提交时,Git 会创建一个新的提交(commit),该提交包含了当前暂存区的所有更改,以及一个与之相关联的提交信息(commit message)。
git commit -m "message"-m 选项允许在命令行中直接提供提交信息。提交信息应该简洁明了地描述你的更改内容。
git commit --amend -m "new message"--amend 选项。这个命令会创建一个新的提交来替换旧的提交,但保留旧的提交的所有更改,只是提交信息(或更改内容,如果也做了新的更改)会被更新。
注意:使用
--amend时要小心,因为它会更改你的提交历史。如果在共享分支上工作(即,正在与团队中的其他人一起工作的分支),最好避免使用--amend,因为它可能会给其他人带来混淆。相反,可以考虑使用git rebase或其他工具来重写或合并提交历史。
在使用Git进行版本控制时,查看代码状态是一个常见且重要的操作,它帮助开发者了解当前工作目录、暂存区以及远程仓库之间的同步状态。
git statusgit status是查看Git仓库状态最常用的命令。它会显示当前分支的状态信息,包括哪些文件被修改、被删除、被暂存,以及当前分支与远程分支的同步状态等。
git status命令并执行。git diffgit diff命令用于显示工作目录中的文件与暂存区或上一个提交之间的差异。
git diff
git diff这个命令显示的是工作区(即当前编辑的文件所在的目录)与暂存区(也称为索引区或staging area,是准备提交到仓库中的文件的一个快照)之间的差异。换句话说,它展示了自上次将更改添加到暂存区以来,对工作区中的文件所做的任何修改。
git diff --cached 或 git diff --staged
git diff --cached
# 或者
git diff --staged这两个命令是等价的,它们都显示的是暂存区与上一次提交(即HEAD指向的提交)之间的差异。这有助于查看已经准备好但尚未提交到仓库的更改。这些更改已经被 git add 命令添加到了暂存区,但尚未通过 git commit 命令提交。
git diff HEAD
git diff HEAD这个命令显示的是工作区与当前分支的最新提交(即HEAD指向的提交)之间的差异。它对于查看自上次提交以来对工作区文件所做的所有修改非常有用。这个命令与不带任何参数的 git diff 类似,但后者默认比较的是工作区与暂存区之间的差异。然而,如果自上次提交以来您没有做任何修改,并且自上次将更改添加到暂存区以来也没有做任何修改,那么这两个命令的输出将是相同的。
git diff:查看工作区与暂存区之间的差异。git diff --cached 或 git diff --staged:查看暂存区与上一次提交之间的差异。git diff HEAD:查看工作区与当前分支最新提交之间的差异。git loggit log命令用于显示项目的提交历史记录。通过查看提交历史,可以了解代码的变化情况。
git log命令并执行。可以使用不同的选项来定制输出信息,如--oneline简化输出。git remote -v:列出当前仓库的所有远程仓库及其URL。git remote show <远程仓库名>:显示与指定远程仓库的详细信息,包括跟踪的分支和最后一次更新的时间。git fetch:从远程仓库获取最新的更改,但不会自动合并到本地仓库。执行后,可以通过git log或git diff查看更新情况。除了命令行工具外,还可以使用图形化的Git工具(如GitKraken、SourceTree等)来查看代码状态。这些工具通常提供更直观、用户友好的界面来显示工作目录、暂存区、提交历史以及远程仓库的状态。
在Git中,分支管理是一个核心功能,它允许我们并行地开发多个功能或修复多个bug,而不会相互干扰。
git branch:不带任何参数时,此命令会列出当前仓库中的所有分支。它会显示当前活跃的分支前有一个星号(*)标记。git branch [branch-name]:这个命令会创建一个新的分支,但是不会自动切换到该分支。创建后,你仍然会留在当前的分支上。git branch -d [branch-name]:删除指定的分支。这个命令只能删除那些已经完全合并到当前分支的分支。如果分支还没有被合并,Git会阻止你删除它,并提示分支尚未合并。如果确实想要强制删除它,可以使用git branch -D [branch-name]。git checkout [branch-name]:切换到指定的分支。如果分支不存在,Git会报错。git checkout -- [file]:这个命令实际上是用来撤销对文件的更改的,而不是用来切换分支的(尽管它的名字可能会让人误解)。它会将指定的文件回滚到最近一次提交(HEAD)的状态,丢弃自那次提交以来对该文件所做的所有更改。注意:从Git 2.23版本开始,
git switch和git restore被引入作为git checkout的子命令,以更清晰地表达其用途。git switch用于切换分支,而git restore用于恢复文件到之前的状态。
git merge [branch-name]:将指定分支的更改合并到当前分支中。Git会尝试自动合并更改,但如果有冲突,它会停下来并让你解决冲突。解决冲突后,需要使用git add来标记冲突已解决,并使用git commit来完成合并提交。在Git中,远程仓库操作是团队协作中不可或缺的一部分。
git pull 命令用于从远程仓库拉取最新代码并尝试合并到当前分支。这是更新本地仓库以包含远程仓库更改的常用方法。
git pull [remote] [branch][remote] 是远程仓库的名称,默认情况下是 origin。[branch] 是要拉取的远程分支的名称,默认情况下是 origin 对应的本地分支(例如,如果当前分支是 main,则默认拉取 origin/main)。[remote] 和 [branch],Git 会尝试从默认的远程仓库和分支拉取代码。git pull --rebase 命令与 git pull 类似,但它不是通过合并来集成更改,而是通过变基(rebase)来集成。这可以创建一个更线性的提交历史,但需要注意,如果变基过程中发生冲突,需要手动解决。git push 命令用于将本地仓库的更改推送到远程仓库。
git push [remote] [branch][remote] 是远程仓库的名称,例如 origin。[branch] 是要推送的本地分支的名称,Git 会尝试将其推送到远程仓库中对应的分支。git push -u [remote] [branch] 命令除了推送更改外,还会设置 [branch] 的上游(upstream)分支为 [remote]/[branch]。这意味着未来的 git pull 和 git push 命令可以省略 [remote] 和 [branch] 参数,Git 会自动使用设置的上游分支。git remote -v这个命令用于列出当前Git仓库配置的远程仓库的详细信息。它会显示每个远程仓库的短名称(shortname)和对应的URL。这对于确认远程仓库的配置是否正确非常有用。
用法:
git remote -v输出示例:
origin https://github.com/username/repo.git (fetch)
origin https://github.com/username/repo.git (push)在这个例子中,origin 是远程仓库的短名称,而 https://github.com/username/repo.git 是对应的URL。括号中的 (fetch) 和 (push) 分别表示用于拉取(fetch)和推送(push)操作的URL。
git remote add [shortname] [url]这个命令用于向当前Git仓库添加一个新的远程仓库。需要指定远程仓库的短名称(shortname)和它的URL。
用法:
git remote add [shortname] [url][shortname]:你选择的远程仓库的短名称,通常用于在命令中引用远程仓库。[url]:远程仓库的URL,可以是HTTP、HTTPS或SSH等协议。示例:
git remote add upstream https://github.com/original-author/repo.git在这个例子中,我们添加了一个新的远程仓库,其短名称为 upstream,URL指向了原始作者的仓库。
git fetch [remote]这个命令用于从指定的远程仓库拉取最新的变更,但不会自动合并到当前分支。这允许查看远程仓库中的变更,并决定是否要将它们合并到本地仓库中。
用法:
git fetch [remote][remote]:可选参数,指定要从中拉取变更的远程仓库。如果不指定,则默认为 origin。示例:
git fetch origin或者,如果之前添加了 upstream 远程仓库,并想从中拉取变更:
git fetch upstream 拉取后,可以使用 git log 查看远程分支的变更,或者使用 git merge 或 git rebase 将这些变更合并到的本地分支中。
git pull 或 git push 之前,最好先使用 git fetch 命令来获取远程仓库的最新状态,但不合并到当前分支。这可以帮助了解远程仓库中是否有新的提交,以及是否可能发生合并冲突。git pull --rebase 可以帮助保持项目历史的清晰和线性,但请注意,变基会改变提交的历史,因此在已经推送到共享仓库的提交上执行变基时要格外小心。在Git中,撤销操作是日常版本控制中非常重要的一部分。
用途:git reset [commit]命令用于将当前分支的HEAD指针移动到指定的提交上,这可以用来撤销一个或多个提交。但需要注意的是,这个命令并不会改变工作区或暂存区的文件内容,除非使用了--hard选项。
详细解释:
git reset [commit]:默认情况下,这个命令会将HEAD指针移动到指定的提交上,但是不会改变暂存区和工作区的文件内容。这意味着,可以使用新的提交来覆盖之前的提交历史,但已经做出的更改仍然保留在暂存区或工作区中。git reset --soft [commit]:这个选项会将HEAD指针移动到指定的提交上,同时保留暂存区和工作区的文件内容不变。这通常用于想要撤销某些提交,但又想保留这些提交中的更改以便重新提交的情况。git reset --mixed [commit](默认模式):这个选项会将HEAD指针移动到指定的提交上,并重置暂存区的内容以匹配该提交的内容,但工作区的内容不会改变。这意味着,已经提交的更改会被放入暂存区,可以重新提交。git reset --hard [commit]:这是最强大的选项,它会将HEAD指针移动到指定的提交上,并同时重置暂存区和工作区的内容以匹配该提交的内容。这意味着,自该提交以来的所有更改都将被丢弃,无法恢复(除非有备份)。注意事项:
git reset --hard之前,请确保已经备份了重要的更改,因为一旦执行,之前的更改将无法恢复。git reset会修改提交历史,因此在团队协作项目中应谨慎使用,并确保其他成员了解这些更改。用途:git reset HEAD <file>命令实际上是将指定的文件从暂存区撤销,即将文件的状态从“已暂存”更改为“已修改”(如果文件在工作区中有更改)或“未跟踪”(如果文件是新添加的且未被提交)。
详细解释:
git add命令将其添加到暂存区,那么这个命令会将这些更改保留在工作区中,但不再准备提交。用途:git checkout -- <file>命令用于恢复工作区中的文件到最近一次提交时的状态,即撤销工作区中对文件的修改。
详细解释:
注意事项:
git checkout -- <file>命令时要小心,因为它会丢弃工作区中对文件的修改。如果确定要撤销这些修改,再执行此命令。git restore --staged <file>来恢复暂存区的文件,以及git restore --worktree <file>或git restore <file>来恢复工作区的文件,以更清晰地表达命令的意图。然而,git checkout -- <file>仍然是广泛支持的,并且在许多情况下仍然可以使用。git stash功能:将当前工作区的变更储存到一个临时区域(stash),以便稍后恢复。这对于需要临时切换到其他分支但又不想提交当前工作进度的场景非常有用。
常用命令:
git stash:将当前工作区的所有变更暂存起来。git stash apply:恢复之前暂存的工作进度,但不会从stash列表中删除该记录。git stash pop:恢复并删除之前暂存的工作进度。这相当于git stash apply后紧接着执行git stash drop。git stash drop:删除stash列表中指定的暂存记录。git stash list:查看当前所有暂存的stash列表。注意事项:
git stash pop或git stash apply之前,确保当前工作目录是干净的,以避免冲突。git add将不需要暂存的文件添加到暂存区,然后执行git stash --keep-index,这样只有未添加到暂存区的文件会被暂存。git tag功能:用于添加、列出或删除标签,标签通常用于标记重要的里程碑,如发布版本。
常用命令:
git tag [tag-name]:为当前分支的最新提交添加一个新标签。git tag -d [tag-name]:删除指定的标签。git tag -l:列出所有标签。git show [tag-name]:显示指定标签的详细信息,包括关联的提交信息。注意事项:
git push origin [tag-name]或git push origin --tags将标签推送到远程仓库。git bisect功能:用于二分查找引入bug的提交。它可以帮助你快速定位到导致问题的具体提交。
使用流程:
git bisect start。git bisect good和git bisect bad。git bisect reset。注意事项:
git reflog功能:查看引用日志,记录了HEAD和分支引用的每一次移动,包括那些被撤销的提交和分支切换操作。这对于恢复误删除的提交或分支非常有用。
使用方式:
git reflog查看引用日志。git reset --hard [commit-hash]或git checkout [commit-hash]来恢复。注意事项:
在Git中,git rebase和git revert是两个强大的进阶命令,它们提供了比git merge更灵活的分支管理和版本控制功能。
功能:git rebase用于将当前分支的提交变基到指定分支上。这意呀着它会将当前分支的提交历史“重放”到另一个分支的最新提交之上,从而创建一个更加线性和干净的提交历史。
基本用法:
git rebase [branch-name]这里,[branch-name]是想要将当前分支变基到的目标分支名。执行此命令后,Git会找到当前分支和目标分支的共同祖先,然后将当前分支上自该祖先以来的所有提交依次应用到目标分支的最新提交之上。
注意事项:
git add命令将更改添加到暂存区,并使用git rebase --continue命令继续变基操作。git rebase --abort命令。功能:git revert用于撤销指定提交的更改,并生成一个新的提交来记录这些更改的撤销。与git reset不同,git revert不会改变项目的历史,而是会创建一个新的提交来“回滚”之前的更改。
基本用法:
git revert [commit-id]这里,[commit-id]是你想要撤销的提交的哈希值。执行此命令后,Git会创建一个新的提交,其内容会撤销指定提交中的更改。
高级用法:
git revert commit_id_start..commit_id_end(注意,这个范围是左闭右开的)。git revert命令。-n或--no-commit选项在撤销后手动调整暂存区,最后使用git commit提交更改。注意事项:
git revert会保留项目的完整历史记录,这对于需要保持项目历史清晰和可追溯性的场景非常有用。git add命令将更改添加到暂存区,并继续执行撤销操作(如果使用了-n选项)。git revert创建的提交信息默认会包含“Revert”字样,以及被撤销提交的哈希值和提交信息。你可以使用-e或--edit选项在提交前编辑这些信息。
git rebase和git revert是Git中非常有用的进阶命令,它们提供了强大的分支管理和版本控制功能。然而,由于它们会改变项目的历史记录(至少在某种程度上),因此在使用时需要谨慎。

这些指令是Git中最基础且最常用的部分,熟练掌握它们将极大地提升版本控制能力和团队协作效率。当然,Git的功能远不止于此,随着学习的深入,将能够掌握更多高级特性和技巧。