关于Git一些问题的总结和补充
- 1.常用Git命令
- 2.Git目录
- 3.Git在工作中的使用流程
- 4.拉取请求(pull request) VS 分支(branch)
- 5.如何从 Git 中删除文件,而不将其从文件系统中删除?
- 6.Git的三种状态是什么
- 7.如果分支是否已合并为master,你可以通过什么方式检测知道?
- 8.Git如何强制切换至其他分支?
- 9.如何找到Git特定提交中已更改的文件列表?
- 10.Git撤销commit(未git push)?
- 11.如果想要在提交之前运行代码性检查工具,并在测试失败时阻止提交,该怎样配置 Git 存储库?
- 12.GitHub、Gitee、GitLab
- 13.如何把本地仓库的内容推向一个空的远程仓库?
- 14.简述Git如何怎样将N次提交压缩成一次提交?
1.常用Git命令
1.1 初始化代码库
-
git init
初始化一个新的Git仓库。在你的项目目录中运行此命令,它会创建一个名为.git的子目录,这个目录包含了所有的Git仓库数据。例如,如果你有一个名为my_project的新项目,你可以进入这个项目的目录并运行git init,这样my_project就成了一个Git仓库。 -
git clone [url]
克隆(即复制)一个现有的Git仓库。这个命令会将远程仓库的所有数据下载到本地,创建一个与原仓库一模一样的副本。例如,如果你想克隆一个远程仓库到本地,可以使用git clone https://github.com/example/my_project.git。
1.2 配置
git config --list
显示当前的Git配置。这个命令会列出所有的配置设置,包括全局配置和仓库级别(如果在仓库目录内运行)的配置。git config --global user.name "Your Name"
设置全局用户名。这是你在提交时Git用来记录是谁做出了更改的信息。例如,git config --global user.name "chourunfat"会将你的用户名设置为"chourunfat"。git config --global user.email "your_email@example.com"
设置全局电子邮件地址。这是与你的用户名一起记录在每次提交中的信息,用于标识提交者。例如,git config --global user.email "jane.doe@example.com"。git config --global core.editor "editor"
设置Git的默认文本编辑器。如果你有特定的文本编辑器偏好,比如想使用Vim或Emacs而不是默认的编辑器,你可以通过这个命令进行设置。例如,git config --global core.editor "vim"。
1.3 增加/删除文件
git add [file]
将新创建的或修改过的文件添加到暂存区。这是准备文件进行提交的第一步。如果你有一个新文件叫做example.txt,你可以通过运行git add example.txt来添加它。git add .或git add -A
将仓库中所有未跟踪的和修改过的文件添加到暂存区。这个命令在你进行了多个文件的更改后非常有用,可以一次性将所有更改准备好进行提交。git rm [file]
从工作区和暂存区中删除指定的文件。这意味着,当你运行git rm [file]时,该文件不仅会从暂存区中被移除,同时也会从工作区中被删除。例如,如果你想删除example.txt文件,可以使用git rm example.txt。这个命令不仅会从Git仓库中删除文件,还会从你的工作目录中删除它。git rm --cached [file]
仅从Git仓库中删除文件,但保留在工作目录中。如果你不小心将一个文件加入到了版本控制中,但实际上想保留它在你的工作目录而不希望Git跟踪,可以使用这个命令。git mv [old_file] [new_file]
移动或重命名一个文件、目录或软链接,并且将这次操作加入到暂存区。例如,如果你想将文件old_name.txt重命名为new_name.txt,可以使用git mv old_name.txt new_name.txt。
1.4 代码提交
git commit -m "commit message"
提交暂存区的更改到仓库历史中,并附加一条提交信息描述这次更改。提交信息应该清晰准确地描述你做了哪些更改和为什么做这些更改。例如,git commit -m "Add login feature"。git commit -am "commit message"
对于已经跟踪的文件(即之前已经添加到仓库中的文件),这个命令可以跳过git add步骤,直接将所有修改过的文件提交到仓库。这个命令不适用于新文件(未被跟踪的文件)。例如,git commit -am "Update README with project details"。git commit --amend
修改最近一次的提交。这个命令会打开你的文本编辑器,允许你编辑上一次提交的信息。如果你在提交后立即发现忘记了添加某些文件的更改或提交信息有误,可以使用这个命令来修正。
1.5 分支
git branch
列出本地仓库的所有分支。执行这个命令时,当前分支会以一个星号(*)标记。git branch [branch_name]
创建一个新分支。这个命令不会自动切换到新分支,只是创建它。例如,git branch feature-x会创建一个名为feature-x的新分支。git checkout [branch_name]
切换到指定的分支。这个命令让你可以在不同的分支之间移动,开始在所选分支上工作。例如,git checkout feature-x会切换到feature-x分支。git checkout -b [branch_name]
创建并切换到新分支。这是git branch和git checkout的快捷组合,常用于开始一个新的功能开发。例如,git checkout -b feature-y会创建并立即切换到feature-y分支。git merge [branch_name]
将指定分支的更改合并到当前分支。这个命令用于将分支的开发成果集成回主分支。例如,如果你在feature-x分支上完成了工作,并想将更改合并回main分支,你首先需要切换到main分支(git checkout main),然后运行git merge feature-x。git branch -d [branch_name]
删除一个分支。当你完成了一个分支的工作并成功合并后,你可能不再需要这个分支,可以使用这个命令将其删除。例如,git branch -d feature-x会删除feature-x分支。如果分支未被合并,可以使用-D选项强制删除。git branch -m [old_name] [new_name]
重命名分支。如果你需要更改分支的名称,可以使用这个命令。例如,git branch -m feature-x feature-x-updated将分支feature-x重命名为feature-x-updated。
1.6 标签
git tag
列出仓库中的所有标签。执行这个命令会显示项目中当前的所有标签。git tag [tag_name]
创建一个轻量标签。轻量标签是指向特定提交的引用,不包括任何额外信息。例如,git tag v1.0会在当前的提交上创建一个名为v1.0的标签。git tag -a [tag_name] -m "tag message"
创建一个带有附加信息的注释标签。注释标签包含创建者的名字、电子邮件、日期,以及一个标签信息。例如,git tag -a v1.1 -m "Version 1.1 release"。git show [tag_name]
显示一个标签的详细信息,包括标签的注释信息和指向的提交。例如,git show v1.0会显示v1.0标签的详细信息。git tag -d [tag_name]删除一个标签。如果你创建了一个错误的标签或者不再需要某个标签,可以使用这个命令来删除它。例如,git tag -d v1.0会删除v1.0标签。git push [remote] [tag_name]
推送一个标签到远程仓库。默认情况下,git push命令不会将标签推送到远程仓库,你需要显式地推送标签。例如,git push origin v1.0会将v1.0标签推送到远程仓库。git push [remote] --tags
推送所有本地标签到远程仓库。如果你想一次性推送多个标签,可以使用这个命令。
1.7 查看信息
git status
显示工作目录和暂存区的状态。这个命令会列出未跟踪的文件、改动未暂存的文件,以及已暂存但尚未提交的更改。git log
查看提交历史。这个命令显示了提交的详细历史,包括提交哈希、作者、日期和提交信息。你可以使用不同的选项来定制显示的日志,比如--oneline、--graph、--decorate等。git diff
查看未暂存更改。默认情况下,git diff显示工作目录中与暂存区不同的更改。如果你想查看已暂存的更改(即将要提交的更改),可以使用git diff --cached。git diff [commit1] [commit2]
比较两个提交之间的差异。这个命令显示两个提交状态之间的代码差异。
git show [commit] - 显示某次提交的详细信息,包括提交的差异改动。这对于理解特定提交所引入的更改非常有用。git blame [file]
查看文件的逐行修改记录。这个命令对于追溯特定行的更改历史和责任归属非常有用。git log --follow [file]
查看文件的更改历史,包括重命名。如果你对一个文件的完整历史感兴趣,这个命令可以提供有用的信息。git reflog
查看本地仓库的引用日志(reflog)。git reflog显示了HEAD和分支指针的最近变动,这对于恢复丢失的提交和理解仓库的状态变化非常有用。
1.8 远程同步
git clone [repository_url]
克隆一个远程仓库到本地。这个命令会创建一个与远程仓库一模一样的副本,包括所有的分支和历史记录。例如,git clone https://github.com/example/repo.git。git remote
查看远程仓库。默认情况下,git remote会列出所有远程仓库的简称。使用git remote -v可以查看远程仓库的URL。git remote add [shortname] [url]
添加一个新的远程仓库。通过这个命令,你可以为仓库添加一个新的远程源。例如,git remote add origin https://github.com/example/repo.git。git fetch [remote]
从远程仓库下载所有的更改,但不自动合并到当前工作。git fetch origin会从名为origin的远程仓库获取最新的更改。git pull [remote] [branch]
从远程仓库下载更改 并自动合并 到当前分支。这个命令是git fetch和git merge的组合。例如,git pull origin master会从origin的master分支拉取最新的更改并合并到当前分支。git push [remote] [branch]
将本地分支的更新推送到远程仓库。如果你对本地分支做了更改并希望分享这些更改,可以使用这个命令。例如,git push origin master会将本地的master分支推送到origin。git push [remote] --tags
推送本地标签到远程仓库。默认情况下,git push不会将标签推送到远程仓库,使用这个命令可以推送所有本地新建的标签。git remote remove [shortname] 或 git remote rm [shortname]
删除一个远程仓库的引用。如果你需要移除对一个远程仓库的引用,可以使用这个命令。
2.Git目录

Git目录(通常是.git目录)位于Git仓库的根目录下,是Git存储项目元数据和对象数据库的地方。这个目录是Git仓库的核心,包含了几乎所有跟踪和管理仓库所需的信息。以下是.git目录中一些关键组件的简述:
-
HEAD
这是一个引用文件,指向当前仓库中被检出的最后一次提交(commit)。它可以是一个分支的引用,如refs/heads/master,表示当前的工作分支。


-
config
这个文件包含了项目特定的配置选项。这些配置可以包括用户名、电子邮件地址、远程仓库的URL等。这些设置是针对当前仓库的,不会影响用户的全局Git配置。

-
objects
这个目录存储所有的数据(如文件内容、目录树、提交对象等)。这些数据以blob(文件内容)、tree(目录结构)和commit(提交信息)对象的形式存在。 -
refs
存放引用的目录,包括分支(heads)、远程跟踪分支(remotes)和标签(tags)。这些文件里记录了各个引用所指向的对象(通常是提交)的SHA-1值。



-
index
这个文件充当暂存区,记录了准备下一次提交的文件的信息。这些信息包括文件名、模式(如执行权限)、时间戳和SHA-1值。 -
hooks
这个目录包含客户端或服务端的钩子脚本,这些脚本在特定的重要动作发生时被触发,如提交前和提交后。

info
包含一个exclude文件,用于定义不需要包含到Git版本控制中的文件模式(类似于.gitignore文件,但仅对当前仓库有效)。

logs
存储了引用的变更历史,例如分支和远程跟踪分支的历史提交信息。这对于恢复数据和理解历史更改非常有用。
.git目录是Git仓库运作的基础,理解其结构和功能对于高效使用Git非常重要。不过,在日常使用中,大部分Git用户不需要直接操作这个目录,因为Git命令行工具提供了所有必要的功能来管理仓库。
3.Git在工作中的使用流程
克隆仓库
使用git clone [repository_url]克隆远程仓库到本地,这样你就有了仓库的完整副本,包括所有分支和历史记录。创建分支
通过git checkout -b [branch_name]创建并切换到一个新分支。这允许你在隔离的环境中工作,不影响主分支(如main或master)。修改和测试代码
在你的本地分支上进行修改和测试。这个阶段包括编写新代码、修复bugs和执行测试等。暂存更改
使用git add [file]或git add .将更改添加到暂存区。暂存是准备提交更改的过程,允许你选择性地控制哪些修改被包含在即将进行的提交中。提交更改
通过git commit -m "commit message"提交你的更改到本地仓库。每次提交都应附带一个清晰的消息,描述进行了哪些更改及其原因。拉取最新更改
在将更改推送到远程仓库之前,使用git pull [remote] [branch]拉取远程分支的最新更改。这有助于减少合并冲突的可能性。解决冲突
如果在拉取最新更改时遇到冲突,需要手动解决这些冲突,然后再次提交。推送更改
使用git push [remote] [branch]将本地分支的更新推送到远程仓库。这样其他人就能看到你的更改了。合并分支
当你完成了在分支上的工作,并且经过测试确认无误后,可以将这个分支合并回主分支。通常,这涉及到发起一个合并请求(Merge Request)或拉取请求(Pull Request),在团队成员审查代码后进行合并。标记发布
发布版本时,可以使用git tag [tag_name]来标记。这有助于记录重要的里程碑,如版本发布。
4.拉取请求(pull request) VS 分支(branch)
"拉取请求(pull request)"和"分支(branch)"是Git和代码协作平台(如GitHub、GitLab等)中两个基本但不同的概念,它们在软件开发流程中扮演着不同的角色:
- 概念上
分支是Git的一个核心功能,允许你在不同版本的代码间安全地隔离和开发;而拉取请求是一个高级功能,主要存在于在线代码协作平台上,用于代码审查和合并的流程。 - 目的上
分支用于隔离开发工作,而拉取请求用于通知和请求其他团队成员审查和合并你在某个分支上的工作。 - 功能上
分支是代码的物理表示,代表代码的不同版本;拉取请求是团队协作的工具,它提供了一个讨论和审查代码的框架,最终目的是改进和合并代码。
简而言之,分支是实际进行代码更改的地方,而拉取请求是当你希望将这些更改并入更广泛的项目时,促进团队沟通和协作的机制。
5.如何从 Git 中删除文件,而不将其从文件系统中删除?
将文件从暂存区移除到工作区,但不删除工作区的文件:
git rm --cached <file_path>
6.Git的三种状态是什么
- 已修改(modified)

- 已暂存(staged)

- 已提交(committed)

7.如果分支是否已合并为master,你可以通过什么方式检测知道?
要知道某个分支是否已合并为master,你可以使用以下命令:
git branch --merged它列出了已合并到当前分支的分支。git branch --no-merged它列出了尚未合并的分支。
在主分支新建一个新分支dev,在dev分支追加内容:


然后commit。

这时候dev分支没有合并为master。需要切换到master分支可以用命令查看:

合并dev代码,然后用命令查看:

8.Git如何强制切换至其他分支?
如果你想要切换分支并丢弃当前分支上的所有本地更改,可以使用-f(或–force)选项。例如,要切换到名为other-branch的分支:
git checkout -f other-branch
这将会强制切换到other-branch分支,丢弃所有未提交的更改。
9.如何找到Git特定提交中已更改的文件列表?
在 Git 中,“特定提交” 是指某个特定的提交(commit),它代表了代码库在某个时间点上的状态。每个提交都有一个唯一的 SHA-1 哈希值(或简称为 “哈希值”),通过这个哈希值可以唯一地标识和引用该提交。
当我们说 “获取特定提交中已更改的文件列表” 时,我们的意思是找到在某个特定提交中所修改、添加或删除的文件。这对于审查更改、代码回顾以及了解某个提交的影响范围非常有用。
如何获取特定提交中已更改的文件列表?
9.1 查找特定提交的哈希值
首先,使用 git log 查看提交历史并找到目标提交的哈希值:
git log
输出示例:
commit abc1234
Author: Your Name <your.email@example.com>
Date: Fri Aug 6 12:34:56 2024 +0000
修复了登录功能的Bug
commit def5678
Author: Your Name <your.email@example.com>
Date: Thu Aug 5 10:20:30 2024 +0000
更新了文档
在这里,abc1234 和 def5678 是提交的哈希值。
9.2 使用git diff --name-only 查看更改的文件列表
git diff --name-only abc1234^ abc1234
这个命令会显示提交 abc1234 相对于它的父提交所更改的文件列表。输出示例如下:
README.md
login.txt
9.3 使用 git diff --name-status 查看更改文件及其状态
如果你还想查看文件的更改状态(如修改、添加或删除),可以使用 git diff --name-status:
git diff --name-status abc1234^ abc1234
输出示例:
M README.md
A login.py
D oldfile.txt
- M 表示文件被修改(Modified)
- A 表示文件被添加(Added)
- D 表示文件被删除(Deleted)
9.4 使用git show
git show 命令也可以显示特定提交中的更改文件列表:
git show --name-only abc1234
输出示例:
commit abc1234
Author: Your Name <your.email@example.com>
Date: Fri Aug 6 12:34:56 2024 +0000
修复了登录功能的Bug
README.md
login.py
或者,使用 --name-status 选项:
git show --name-status abc1234
输出示例:
commit abc1234
Author: Your Name <your.email@example.com>
Date: Fri Aug 6 12:34:56 2024 +0000
修复了登录功能的Bug
M README.md
A login.py
D oldfile.txt
9.5 总结
“特定提交” 是指代码库在某个时间点上的状态,可以通过唯一的哈希值标识。要获取特定提交中已更改的文件列表,可以使用以下命令:
git diff --name-only < commit >^ < commit >:仅列出更改的文件名称。git diff --name-status < commit >^ < commit>:列出更改的文件名称及其状态。git show --name-only < commit >:显示提交详细信息并列出更改的文件名称。git show --name-status < commit >:显示提交详细信息并列出更改的文件名称及其状态。
10.Git撤销commit(未git push)?
10.1 情景
我们在git仓库写完代码后,一般有如下操作:
git add .
git commit -m “fix bug”
正常情况下一步操作是git push,但是实际项目中会出现两种情况导致无法push
- 在执行
git push之前我们发现刚才添加的内容是错误的 push之后,需要别人review,别人review的时候发现你是错误的代码,拒绝merge
10.2 撤销操作
撤销commit的操作
git reset --[soft | mixed | hard] HEAD^
下面重点讲一讲,soft、mixed、hard几个参数的区别。
--mixed
不删除工作空间改动代码,撤销commit,并且撤销git add .。mixed为默认参数,也即git reset --mixed HEAD^与git reset HEAD^效果一样--soft
不删除工作空间改动代码,撤销commit,不撤销git add .--hard
删除工作空间改动代码,撤销commit,撤销git add .,注意完成这个操作后,就恢复到了上一次的commit状态。
注意:如果只是commit注释内容写错,就执行git commit --amend去修改commit的内容即可
下面举个例子:项目当前有个index.txt:


修改index.txt内容:


使用git reset --mixed:

如上,mixed不删除工作空间改动代码,撤销了commit,并且撤销了git add .。 然后执行下面命令:

使用git reset --soft:

如上,soft不删除工作空间改动代码,撤销了commit,未撤销git add . 然后执行下面命令:

使用git reset --hard:

如上,hard删除了工作空间改动代码,撤销了commit,撤销了git add . 注意完成这个操作后,就恢复到了上一次的commit状态。这时候看一下文件内容,恢复到了上一次的commit状态:

修改一下index.txt内容:

然后提交内容:

如上,发现commit的内容有些问题,想要修改commit注释,可以执行git commit --amend去修改。


按:wq退出保存。然后查看历史版本:

11.如果想要在提交之前运行代码性检查工具,并在测试失败时阻止提交,该怎样配置 Git 存储库?
要在提交之前运行代码检查工具并在测试失败时阻止提交,可以使用 Git 的钩子(hook)功能。具体来说,你可以配置一个 pre-commit 钩子来执行代码检查工具,并在检查失败时阻止提交。以下是配置 pre-commit 钩子的步骤:
创建或编辑 pre-commit 钩子文件:
Git 钩子位于项目的.git/hooks目录中。pre-commit钩子在提交操作之前执行。创建或编辑 .git/hooks/pre-commit文件:
touch .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
编写钩子脚本:
在pre-commit文件中编写钩子脚本,调用你的代码检查工具。例如,如果你使用flake8作为Python代码检查工具,可以编写如下脚本:
#!/bin/sh
# Run code check
flake8 .
# Check the exit status of flake8
if [ $? -ne 0 ]; then
echo "Code check failed. Please fix the issues before committing."
exit 1
fi
# Continue with the commit if code check passes
exit 0
确保钩子文件可执行:
确保pre-commit文件是可执行的:
chmod +x .git/hooks/pre-commit
- touch 创建文件
- chmod:是一个 Unix 命令,用于改变文件的权限(modes)。
- +x:表示为文件添加执行权限(executable permission)。在 Unix 系统中,文件需要有执行权限才能被当作脚本运行。
关于代码自动检测和拦截,详情见我写的文章https://blog.youkuaiyun.com/fageaaa/article/details/145474065。
12.GitHub、Gitee、GitLab
- GitHub
是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯的版本库格式进行托管,故名GitHub。 - Gitee(码云)
国内的一个代码托管平台,由于服务器在国内,所以相比于GitHub,码云速度会更快。 - GitLab
一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。
13.如何把本地仓库的内容推向一个空的远程仓库?
如果还没有初始化本地仓库,首先需要创建一个新的Git仓库,在命令行页面输入下面命令:
git init
执行命令后,要提交的代码目录下会创建“.git”文件夹。

给该空项目添加一点内容(创建index.txt):

将需要提交的文件添加到Git仓库中:
# 添加所有文件到暂存区
git add .
将暂存区中的文件提交到本地仓库:
# 提交更改,并附上提交信息
git commit -m "提交信息"
若你已经在github/gitee或其他托管平台创建好了远程仓库,将远程仓库添加到本地仓库中。注:origin 空格后面写你自己仓库的远程地址:
# 使用HTTPS URL
git remote add origin https://github.com/username/my_project.git
将本地仓库的内容推送到远程仓库,master是远程仓库的分支:
# 推送master/master分支的所有内容到远程仓库
git push -u origin master
14.简述Git如何怎样将N次提交压缩成一次提交?
使用git rebase -i命令就可以将从最后一次提交往前的多次提交合并为一次。
如下,初始化项目,多次提交记录:


查看历史版本记录:

假如我们要把555、444、333、222的记录压缩成一次提交,那么git rebase -i后面跟的参数应该是想要合并的最前面commit id的上一个,就是d534…这个:
git rebase -i d53412d6d19fa072efb2220d14ac298740fef3e5
之后会弹出现目的编辑窗口,这是一个vim编辑的文本,需要使用vim命令进行编辑:

首先,输入i命令,进入编辑模式。在这个界面中,除了第一行之外的所有pick命令前的文字都应该更改为 squash 或者简写的s,这样 Git 就会将这些提交合并到第一个提交中。

然后按esc键退出输入模式,输入:(英文冒号)进入底线命令模式,再输入wq即保存后退出。
之后会展示如下界面,进行提交注释处理。这里编辑的是我们为什么要合并的原因:

保存之后,git log查看,这里commit变了(正常,因为文件变了)


1821

被折叠的 条评论
为什么被折叠?



