新分支只有一些未提交的更改 长:为什么这是答案要了解的分支名称 git checkout还有另一个窍门

如何解决新分支只有一些未提交的更改 长:为什么这是答案要了解的分支名称 git checkout还有另一个窍门

我正在尝试使用一些未提交的更改来创建新分支,是否可以仅将某些更改导入到新分支中?

解决方法

Matt's point above是,根本没有任何“未提交的更改”。 git status 报告“为登台所做的更改”和“没有登台进行的更改”,该报告本身就是一种谎言,旨在使Git更加可用。 (是否真的实现了这完全是另一个问题。)

最后,这意味着解决方案很简单:只需创建新分支,添加所需的内容,然后运行git commit。 (请勿对-a使用git commit选项。)

长:为什么这是答案

了解所有这些的关键部分是:

  • Git与提交有关。
  • 商品包含快照,而不是差异。
  • Git从建议的快照进行新提交,该快照位于Git所谓的 index 临时区域,和(很少有这些天)缓存。这三个名称都是同一件事。
  • 在工作树中可以查看和使用的文件与Git索引中的副本 1 分开。

最后一点是,当您进行提交时,每个“活动”文件实际上有三个副本:

  • 一个副本严格是只读的,存储在当前提交中。您可以让Git读出来,但是没有任何东西-甚至Git本身都无法更改。

  • 第二个副本(请参见脚注1)位于Git的索引中。

  • 您在工作树中看到并使用的副本实际上并未由Git本身使用(但请参见下文)。 Git将在git checkout上将已提交的文件复制到Git的索引和您的工作树中。如果您更改了工作树副本,则新的git commit将不会使用更新后的文件。相反,它将提交Git索引中的副本。

这就是为什么在提交之前始终必须git add个文件的原因。 2 git add步骤告诉Git:将此文件的工作树副本复制到您的索引副本。作为此复制过程的一部分,Git实际上准备了该文件的即将提交的版本(它是一种特殊的,Git格式的只读格式,并且已预先删除重复数据)因此,所有使用相同内容的提交,只需重新使用准备好的文件即可。

换句话说,在任何时候索引中的内容是将在您提交的 next 提交中的文件集。这直接导致git status告诉您的内容:

  • 首先,git status打印出on branch master之类的内容以及其他有用的内容,在这里我们将忽略它们。

  • 接下来,对于当前提交中的每个文件,Git 将该文件与索引中的文件进行比较。如果两者相同,Git则什么也没说。如果它们不同,则Git会说该文件已被暂存以进行提交。如果索引中缺少该文件,则Git表示已将其删除;如果索引中的文件不在提交中,则Git表示这是一个新文件。但是这两种方式都是“暂存提交”的,因为索引包含建议的下一个提交。索引中的某些内容与当前提交中的内容匹配,因此Git只是不提及它。

  • 第三,对于 index 中的每个文件,Git将该文件与工作树中的文件进行比较。如果两者相同,Git则什么也没说。如果它们不同,则Git表示该文件未上演提交。如果文件丢失,Git会说它已被删除。

  • 最后,在您的工作树中但不在索引中的文件有一种特殊情况。这些是您的未跟踪文件。 Git分别列出了它们。 (如果它们在.gitignore中列出,则Git会阻止有关未跟踪文件的投诉。)

因此,每当Git谈论更改时,无论是分阶段的还是非分阶段的,这实际上意味着文件的各种副本是不同的。从字面上看,提交中的副本是无法更改的:它们一直冻结,或者至少在提交本身存在的时间内被冻结。索引中的副本采用冻结和重复数据删除的格式,但是可以通过覆盖来更改 git add就是这样做的。您可以根据需要处理工作树中的副本。除了git add将这些文件复制到Git的索引中,以及git checkout用一些提交中的文件替换您的工作树文件之外,您还可以根据需要使用该工作树。


1 从技术上讲,索引包含对已删除重复项的内部Git blob对象引用,而不是文件的副本。提交还在内部使用这些Blob对象,因此这就是文件的索引“副本”准备就绪的原因。

2 当您使用git commit -a时,Git本质上为您完成了所有文件的git add。本文中的 essentially 一词是Git这样做的方式,即在提交本身失败的情况下使用额外的临时索引。这个额外的索引使Git可以“撤消”该特定情况的添加。如果使用git commit --only,事情会变得更加复杂:这时,Git生成了两个临时索引文件。在这里,我们将忽略这种情况。

请注意,git add中的git commit -agit add -u大致相同:它仅对Git 已经在其索引中的文件起作用。如果您有一个全新的文件,但Git的索引中还不存在,则您仍然必须手动git add进行该操作。


要了解的分支名称

我在上面提到,提交包含快照,正如我们刚刚看到的那样,快照是根据运行git commit时Git索引中文件的副本构建的。但是还有更多关于每次提交的知识。每个数字都有编号,并具有随机外观(但实际上根本不是随机的)哈希ID 。 Git在内部使用这些数字从其“所有内部哈希对象”的大型数据库中读取实际的提交数据。

因此,要查找提交,Git需要其哈希ID。但是每个提交本身都具有其前一个直接提交的哈希ID,Git将其称为提交的 parent 。这意味着如果我们有很长的提交链,我们可以像这样绘制它:

... <-F <-G <-H

其中每个大写字母代表一个大的丑陋哈希ID。链中的 last 提交是提交H,在提交H内部,Git拥有每个文件的完整快照, plus 一些信息有关提交本身的信息:提交者和时间,例如,上一个提交G的哈希ID。

通过读取提交H,Git可以获得早期提交G的ID。将G中的快照与H中的快照进行比较,Git会向您显示在这两次提交之间发生了什么更改。同样重要的是,由于提交G包含较早提交F的哈希ID,因此Git可以使时间回到过去。 F依次包含更早提交的哈希ID,依此类推。

这里最棘手的部分是Git必须以某种方式找到提交H。这是分支名称的来源。分支名称仅保存链中 last 提交的哈希ID。所以我们最终得到:

...--F--G--H   <-- master

名称 master使Git可以轻松找到提交H。该提交使Git可以找到每个较早的提交。在Git中,历史就是这样工作的:都是后退。我们只是从头开始,然后根据需要向后工作。

要创建新的分支名称,必须选择一些现有的提交。通常,您将从当前提交开始,这是当前分支上的最后一次提交。 git branchgit checkout -b命令将创建新的分支名称,以便选择相同的提交:

...--F--G--H   <-- master,newbranch

现在我们还需要一件事,那就是一种方法来告诉我们正在使用的这两个名称中的哪个-git status会在显示on branch B时显示,某些 B 。因此,我们将特殊名称HEAD附加到一个分支名称。如果我们在分支机构master上,我们将:

...--F--G--H   <-- master (HEAD),newbranch

git checkout还有另一个窍门

请注意,两个名称选择相同的提交!当我们git checkout newbranch时,我们得到:

...--F--G--H   <-- master,newbranch (HEAD)

,但我们仍在使用提交H。这仍然是当前的提交,并且由于我们没有更改提交,因此git checkout不会触及Git的索引或工作树。这意味着我们可以像创建git checkout -b一样创建一个新分支并切换到该分支,而不会弄乱其他任何状态。

现在我们有了这个新分支,并且正在使用它,现在,我们可以使用git add(甚至是git add -p)来有选择地更新Git索引中的特定文件。当我们运行git commit时,Git将打包其索引并进行新的提交I

...--F--G--H   <-- master
            \
             I   <-- newbranch (HEAD)

一旦Git进行了新提交(从当时Git索引中的内容开始),Git便将新提交的哈希ID写入当前分支,即newbranch,因为HEAD是附加到newbranch。现在,该名称标识了分支上的最新提交。

(如果愿意,现在通常可以切换回master。这里的关键是通过将未暂存的文件写入Git的索引以使其暂存,然后将索引写入到提交中,这三个这些文件匹配。只有索引副本和工作树副本不同的不需要文件需要替换。有关更多详细信息,请参见{ {3}}。)

,

其中一些命令有些不透明(其中两个具有破坏性)。如果您不确定他们会做什么,那么在尝试之前,请先阅读本部分内容。

git add some_file some_directory

git add只能按文件或目录添加(实际上,常见的git add .只是将当前目录添加为目录)。

git commit -m "temp"

创建一个我们将丢弃的临时提交。

git add .

添加其他所有内容,以便我们可以将其隐藏起来。

git stash

将当前的工作状态存储在缓冲区中(我们将在稍后将其恢复)。

git checkout -b some-branch

将当前的工作树(包括“ temp”提交)带到所需的新分支。

git checkout -

“-”是用于返回到您所在的上一个分支的快捷方式。

git rev-parse HEAD^^ | pbcopy

这是一堆。 。 。并且最好是单独尝试一下。

git rev-parse HEAD ^将返回当前分支的最新提交信息。

添加第二个类似HEAD ^^的^然后将引用第二个^。 。 。等

管道到pbcopy(MacOS上的系统剪贴板)只是为了方便。您可以省略此部分,而只需突出显示终端的输出即可。

git reset --hard <some_sha>

:警告:破坏性行动:警告:

这会将当前的工作状态恢复为所需的提交(删除所有其他内容)。

在这种情况下,我们将其他所有内容都存储在存储中,这样就可以了。

git stash pop

带回我们存储在储藏物中的东西。


在Mac上,这是一种方法(虽然非常手动):

git add <file(s)>
git commit -m "temp"
git add .
git stash
git checkout -b new-branch
git checkout -
git rev-parse HEAD^^ | pbcopy
git reset --hard <paste from clipboard>
git stash pop

将您留在最后的状态:

您现在有了一个分支“ new-branch”,其中在“临时”提交下提交了代码更改。

您的主分支没有新分支中的更改。


如果我决定我在分支上所做的工作不是我要开发的功能的方向,通常我会使用类似这样的流程。 。 。但是也许我不想完全删除代码(以防万一以后需要)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-