# Git使用 **Repository Path**: comrade-kobayashi/git-usage ## Basic Information - **Project Name**: Git使用 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-04 - **Last Updated**: 2026-01-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Git https://learngitbranching.js.org/?locale=zh_CN ## 本地仓库操作 ### 创建本地仓库 1. 命令:git init - 不带参数命令时:在当前目录下创建一个git仓库; - 会在该目录下创建一个名为 .git 的隐藏文件夹,这个文件夹包含了所有与Git版本控制相关的元数据(如日志、提交历史等); 2. .gitignore文件:在Git仓库中用于指定不被Git跟踪的文件和目录 - 语法: - 空行:用于分隔不同的模式; - 以‘#’开头的行:注释 - 斜杠‘/’:目录分隔符 - 星号‘*’:通配符,匹配0个或多个任意字符; - 叹号‘!’:用于否定某个模式(排除某些被前序模式忽略的文件或目录) - 双星号‘**’:表示匹配多级目录 ### 提交相关 - git add命令 1. 作用:将文件的新内容(包括增、删、改)添加到暂存区 2. 语法: - 添加单个文件:git add filename - 添加所有更改(当前目录及子目录下所有新文件、修改过的文件):git add . - 添加已删除的文件(在工作目录中删除了文件,需使用git add来通知Git这个删除操作也需要被包含在下次提交中):git add path/to/deleted_file - git rm命令 1. 作用:从工作目录和暂存区中同时移除文件 (彻底删除一个文件 ) 2. 语法: - 移除并停止跟踪单个文件:git rm filename - 仅从暂存区移除文件但保留在工作目录中:git rm --cached filename - git commit命令 1. 作用:用于将暂存区中的更改正式保存到本地仓库中,创建一个新的提交(commit) 2. 语法:git commit [-a|--all] [-m | -F ] - git commit -m "msg":直接在命令行中指定提交信息 - git commit -F file:从一个文件中读取提交信息 - git commit -am "msg":相当于先使用git add将已跟踪文件的修改内容添加到暂存区,然后使用git commit -m "msg"为这些文件保存至本地仓库 3. git commit命令背后 - Git仓库中的提交记录保存的是当前目录下所有文件的快照,就像是把整个目录复制,然后再粘贴一样,但比复制粘贴优雅; - Git 希望提交记录尽可能轻量,因此在每次进行提交时,它并不会盲目地复制整个目录。条件允许的情况下,它会将当前版本与仓库中的上一个版本进行对比,并把所有的差异打包到一起作为一个提交记录; - Git还保存了提交的历史记录。这也是为什么大多数提交记录的上面都有parent节点的原因。 - git log 命令 1. 作用:查看提交记录,该命令会显示从最近到最远的所有提交记录,每条记录包括提交的哈希值、作者、日期和提交信息 2. 语法: - git log --oneline:将每个提交压缩为一行显示; - git log --author="name":查看指定作者的提交记录 - git log --oneline --graph --all:以文本方式绘制分支结构图,非常适合用于帮助理解项目的历史和分支合并情况 - git log -p :查看某个具体文件的改动 - git log -- filename:查看指定文件的提交历史 - git show 命令 1. 作用:查看提交的信息 2. 语法: - git show :查看某次提交的具体更改内容。 ### 撤销操作 - git reset命令 - 作用:将当前分支的指针移动到另一个位置,并可以选择性更新暂存区和工作目录,主要有三种模式:--soft、--mixed(默认)、--hard - 语法: - 仅移动分支指针,不影响暂存区和工作目录:```git reset --soft <位置>``` - 移动分支指针并重置暂存区以匹配指定的提交,但不改变工作目录:```git reset <位置>``` - 移动分支指针,重置暂存区和工作目录至指定提交的状态,所有未提交的更改都将丢失:```git reset --hard <位置>``` - 总结:git reset命令把分支记录回退几个提交来实现撤销这一操作,相当于回到过去。其向上移动分支,原来指向的提交记录就跟从来没有提交过一样。 - git revert命令 - 作用:创建一个新的提交,这个提交用于抵销一个或多个先前提交的更改,相当于历史既然已经发生,只能采取措施补救而无法回到过去。(更安全,不改变项目历史,而是添加新的提交来撤销理性) - 语法:```git revert <位置>``` - 总结:操作远程分支时,使用git revert之后再推送 - git restore命令 - 作用:提供一种更直观的方式撤销工作目录中的更改或从索引(暂存区)中恢复文件。 - 语法: 1. 恢复工作目录中的文件:```git restore ```,当对某个文件做了修改但还未添加到暂存区时(即未执行 git add),可以从仓库中恢复文件; 2. 从暂存区中移除理性:```git restore --staged ```,即使用--staged取消暂存这些文件 ### 分支操作 #### 分支相关概念 - Git分支只是简单地指向某个提交记录——仅此而已,其非常轻量,因此许多使用者建立**早建分支!多用分支** - 创建再多的分支也不会造成储存或内存上过多的开销,将工作按逻辑分解到不同的分支要比维护那些特别臃肿的分支简单多; - 分支&提交记录:其实使用分支等价于基于某个提交以及它所有的parent提交来开展新的工作 #### 分离HEAD - HEAD:在Git中,HEAD是一个重要概念,它实际上是一个指针,指向当前所在的提交。HEAD通常指向当前所在的分支的最新提交。 - 默认情况下,HEAD指向当前分支的最新提交,这意味着当你在某个分支上进行新的提交时,HEAD会自动移动到这个新的提交。 - 分离头指针:当你在特定的提交而不是在分支上工作时,这种情况被称为“分离头指针”状态,如执行git checkout commit-hash时检出仓库中指定的hash指针时,HEAD直接指向具体的提交而不是分支名。 - 分离HEAD指针: 1. 命令:git checkout <分支名/提交HASH值>:将HEAD指针指向指定的提交 #### 相对引用 - 相对引用:主要是解决移动HEAD指针时需要使用HASH值的问题,提供一个相对简单的操作方法 - 相对引用的种类: 1. "^":向上移动1个提交记录 2. "~number":向上移动number个提交记录 - 相对引用的使用: 1. 可以作用于分支名、HEAD; 2. 可以组合使用 - 相对引用的区别: 1. '^#':后面的数字含义为合并提交记录的第几个parent提交。 2. '~#':向上返回几代 #### 分支创建、删除、切换、移动 - 创建分支命令: 1. 在当前HEAD处创建分支:git branch 分支名 2. 在当前HEAD处创建分支并切换到该分支:git branch -b 分支名 - 删除分支命令: 1. git branch -d/-D 分支名 - -d:正常删除 - -D:强制删除 - 切换分支命令: 1. git switch 分支名 2. git checkout 分支名:即将被git switch取代 - 查看分支命令: 1. git branch:查看本地分支,当前所在分支前会以‘*’进行标记 2. git branch -a:查看所有分支,包含远程分支 - 移动分支 - 命令:```git branch -f <分支名> [位置]``` - 作用:强制移动分支,使其处于指定的位置。多数情况下是通过HEAD的相对引用操作的 - ```[位置]```:可选参数,表示希望分支的新位置,可以是一个提交哈希、分支名、标签或相对引用。如果不提供则默认使用HEAD的位置 #### 分支合并 - 对提交记录进行整理有助于我们的主分支不合并一些操作。例如:主分支主要是稳定版本,而开发分支包含调试记录的提交。 - git cherry-pick命令: - 作用:将一些提交"复制"到当前所在位置(HEAD)下面,它允许你有选择性地应用某个提交的更改。 - 语法:```git cherry-pick <提交号>``` 1. 选择单个提交:git cherry-pick 提交哈希 2. 选择多个提交:git cherry-pick 提交哈希1 提交哈希2 ... 3. 选择指定范围提交 git cherry-pick 提交哈希1...提交哈希2 4. 放弃操作:git cherry-pick --abort - 分析: 1. 本质是创建新提交而不是简单粘贴,它会创建一个全新的提交(包括新的父提交、新时间戳、新的作者/提交者信息),因此会需要身份信息 - git merge命令 - 作用:把一个分支的提交历史合并到当前所在的分支中,常用于将开发分支合并到主分支、合并功能分支、或者合并远程更新。 - 语法:```git merge ``` - 分析: 1. 将会合并指定分支到当前分支; 2. 保留合并操作本身的历史记录(会生成一个合并提交) - git rebase命令 - 作用:用于重新应用一系列提交到另一个分支上,从而使得提交历史更加清晰、线性。与 git merge 不同,rebase 不会保留原始的合并信息,而是将一系列提交“移植”到目标分支的新起点上。 - 语法:```git rebase 【选项】【上游分支】【待变基分支】``` 1. git rebase <分支1> <分支2>:取出分支2的一系列提交记录,"复制"它们,然后在指定的分支1处逐个放下去,并把当前分支移动到那个位置。 - base:可以是一个分支名、提交哈希或远程分支 - 用法: 1. git switch feature 2. git rebase main - 分析: 1. git rebase会先找出feature分支相对于目标分支main共同祖先的所有提交,暂存这些提交; 2. 将feature分支移动至main的最新提交; 3. 将暂存的提交重新应用于feature分支。 - 结果:feature分支的提交历史看起来像是在main分支的最新提交基础上开发的 - git rebase -i命令 - 作用:交互式变基,允许在不改变项目最终结果的前提下,重写提交历史,包括下面的功能 1. 合并多个提交(squash) 2. 修改提交顺序 3. 删除不必要的提交 4. 拆分提交 5. 修改提交信息 - 语法:git rebase -i [HEAD~3|hash_code] - 交互流程:使用该命令后会经历以下交互方式 1. 打开一个文本编辑器,用于编辑提交历史,修改后需保存; 2. 再次打开一个文本编辑器,用于编辑合并后的提交信息,修改后需保存; - HEAD~3|hash_code:要修改的提交 1. HEAD~3:当前HEAD指针向上3个节点均修改 2. hash_code:当前指针至最远的hash_code(含)之间的节点均修改 #### Git Tag标记 - git tag用于给特定的提交打上标签,以标记重要的里程碑(如发布版本)。标签分为两种类型:轻量级标签和附注标签。 - 轻量级标签:只是一个简单的指针,指向某个提交; - 附注标签:包含更多信息,如标签名、标签消息、标签创建者、日期等 ,它们是独立的对象,存储在Git数据库中; - git tag相对分支的特点: 1. git tag并不会随着新的提交而移动; 2. 不能切换到某个标签上面进行修改提交; 3. 切换到标签位置时,会进入分离HEAD状态; - 命令: 1. 创建一个轻量级标签:```git tag v1.0 []``` 2. 创建一个附注标签并添加消息:```git tag -a v1.0 -m "Release version 1.0" []``` 3. 查看所有标签:git tag -l 4. 查看特定标签的详细信息(仅适用于附注标签):git show v1.0 5. 切换到某个标签:git checkout TAG - 推送标签: - 默认情况下git push不会推送标签到远程仓库 - 命令: 1. 推送单个标签:git push origin v1.0 2. 推送所有标签:git push origin --tags #### git describe - 用于生成一个描述当前提交的字符串。这个字符串通常基于最近的标签,并且包含了从该标签到当前提交之间的提交数量和当前提交的短哈希值。 - 语法:```git describe ``` - 输出内容:假设项目最近的标签是 v1.0,并且从 v1.0 到当前提交之间有 3 次提交,当前提交的短哈希值是 abc1234。则输出为:v1.0_3_gabc1234 ## 远程仓库操作 - 本地仓库:存在本地的Git仓库; - 远程仓库:托管在网络上的Git仓库; - 远程:一个指向远程仓库的别名,通常默认为origin(这个别名存储在.git/config文件中); - 分支:代码开发的不同路线,远程仓库的分支通常命名为remote-name/branch-name,如origin/main ### 添加、删除远程仓库链接 - git remote add <远程仓库名> URL - 作用:用于添加远程仓库链接。实际上这个操作的含义是关联两个仓库(一个是本地仓库,另一个是远程仓库),为本地仓库添加了一个引用(类似于分支),这个引用指向远程仓库。 - 通过这个命令可以指定一个远程仓库的名字、它的位置(URL),这样就可以在本地仓库中引用该远程仓库并与这进行交互了。 - git remote -v - 作用:查看已配置的远程仓库 - git remote remove|rm <远程仓库名> - 作用:删除某个远程仓库的配置 ### 从远程仓库下载更新 - git fetch <远程仓库名> - 作用:获取远程仓库的所有更新(不会自动合并) 1. 下载指定远程仓库上所有分支的最新状态(包括提交历史); 2. 将这些信息存储在本地仓库中,更新名为remote-name/branch-name的远程跟踪分支 ### 获取并合并远程更新 - ```git pull [remote-name] [remote-branch-name]``` - 作用: 1. 从指定的远程仓库获取当前分支对应的远程分支的最新更新; 2. 并将变更合并到当前的本地分支 - ```git pull --rebase [remote-name] [remote-branch-nmae]``` - 作用:相对于上一命令,--rebase参数改变了第2步操作,它会将本地提交“重新播放”在获取的远程更新之上,以生成更加线性的历史记录 ### 将本地提交推送到远程 - ```git push [remote-name] [local-branch-name]:[remote-branch-name]``` - 作用:将本地分支上的新提交上传到指定的远程仓库,并更新该远程仓库对应的分支 1. git push:推送当前分支到设置的上游(upstream)分支 2. git push origin main:将本地的main分支推送到远程origin的main分支 3. git push origin feature/login:将本地feature/login推送至origin的feature/login分支 4. git push origin :branch-name:删除远程仓库上的branch-name分支 5. git push origin --delete branch-name:同上 ## Git Pull - 可以将远程分支获取的变化更新到本地仓库的分支上,如利用以前学习的命令: 1. git merge o/main 2. git cherry-pick o/main 3. git rebase o/main - 从远程仓库获取数据,而后将更新同步到本地仓库的本地分支上需要2步,但Git提供了专门的命令完成这个工作:git pull - 命令: - git pull <远程分支名> - git pull --rebase - 作用: ## 远程服务器拒绝(Remote Rejected) - 在一个大的合作团队中工作,很可能main被锁定了,需要一些Pull Request流程来合并修改; 1. 远程服务器拒绝直接摄像头(push)提交至main,因为策略配置要求pull requests来提交更新; 2. 应该按照流程,新建一个分支,推送(push)这个分支并申请pull request,但是你忘记并直接提交给了main,现在你卡住并无法推送你的更新; 3. 新建一个分支feature,推送到远程服务器。然后reset你的分支和远程服务器保持一致,否则下次你pull并且他人的提交和你冲突的时候就会有问题; ## 远程追踪 - 引言:Git好像知道main与o/main是相关的,存在着以下两种关联: 1. pull操作时,提交记录会被先下载到o/main上,之后再合并到本地的main分支,隐含的合并目标由这个关联确定的; 2. push操作时,我们把工作从main推送到远程仓库的main分支(同时会更新远程分支o/main),这个推送的目的地也是由这种关联确定的 - 原理:main和o/main的关联关系是由分支的“remote tracking”属性决定的,main被设定为跟踪o/main——这意味着为main分支指定了推送的目的地及拉取后合并的目标。 - 如何设置该属性:克隆仓库时由Git自动设置。克隆时,Git会为远程仓库中的每个分支在本地仓库中创建一个远程分支(比如o/main),然后再创建一个跟踪远程仓库中活动分支的本地分支,默认情况下这个本地分支被命名为main。 - 这就是克隆时出现```local branch "main" set to track remote branch "o/main"```提示的原因 - 手动指定本地仓库的分支跟踪远程仓库在本地的分支(o/main) 1. git checkout -b totallyNotMain o/main:新建一个分支totallyNotMain,并跟踪o/main分支 2. git branch -u o/main foo:创建foo分支并跟踪o/main分支,若存在foo分支,可简化命令```git branch -u o/main```【这条命令没有验证过】