如何使“ git stash”拒绝污迹未因此而上演和上演的变化?

发布于 2025-02-03 11:40:34 字数 1145 浏览 2 评论 0原文

问题

如何进行

  1. git stash 错误如果既有尚未上演又上演更改,我尚未指定- 上演-s)或- keep-index-k),或
  2. 进行git Stash默认为<- keep-index如果没有- 上演选项的调用?

理想情况下,作为全局配置选项。

现在动机

几次:

  1. 我仔细git add -p只是我要提交的更改(有时提前对文件进行了临时编辑,当我想拉开两个变化的原子,这些变化恰好碰到相同的变化行或相邻行,git与之挣扎的行),然后
  2. 我认为“我只是在花时间思考一个好的提交消息之前迅速将其他未分段的更改藏起来”,因此
  3. 我键入<代码> git stash ,浪费了步骤1的工作,因为git在这种情况下程序可以做的最愚蠢的事情 - 默认情况下,默认情况下,没有机会中止或撤消,藏匿所有变化,分阶段和未分段的变化,都融合到一个差异中而没有任何区别。 (编辑:答案显示git实际上保留了藏匿时的区别,我只是不知道如何检索它)

现在,如果我是计算机程序,我总是只执行git提交-m'todo: - - 在git stash之前amend此提交,或者我始终记得键入git stash -k。但是我发现更自然地认为“我会尽快将这些未分段的更改库存,然后专注于编写良好的提交信息的更大的心理任务”,

实际上是在考虑这一点,我一直在使用git几乎每天几乎每天都有十年的时间,而我有从不想要git stash将上演更改,更不用说融合了上演和未分段的更改。我可以看到,如果您正在分阶段进行一组更改,然后您想将整个事情藏起来,但是对我来说,这是一个非常小的时间窗口 - 大多数情况下,如果我有分阶段的更改和未分段的变化,它们有意义地不同的变化,我尚未完成将其分为最佳原子委员会。

Question

How do I either

  1. make git stash error out if there are both unstaged and staged changes and I haven't specified either --staged (-S) or --keep-index (-k), or
  2. make git stash default to --keep-index if invoked without the --staged option?

Ideally as a global config option.

Motivation

Several times now:

  1. I carefully git add -p just the changes I want to commit (sometimes with temporary edits to files beforehand, when I want to pull apart two atoms of change which happen to touch the same lines or adjacent line, which git struggles with), then
  2. I think "I'll just quickly stash those other unstaged changes before taking the time to think of a good commit message", and so
  3. I type git stash, wasting the work of step 1, because git does the dumbest thing a program can do in that case - destroys user information by default without opportunity to abort or undo, by stashing all changes, both staged and unstaged changes, blended into one diff without any distinction. (edit: the answers reveal git actually preserves the distinction when stashing, I just didn't know how to retrieve it)

Now if I was a computer program, I'd always just execute git commit -m 'TODO: --amend THIS COMMIT' before git stash, or I'd always remember to type git stash -k. But I find it more natural to think "I'll stash these unstaged changes real quick for later, then focus on the larger mental task of writing good commit message"

In fact come to think of it, I've been using git for close to a decade almost daily, and I have never wanted a git stash to stash staged changes, let alone fuse staged and unstaged changes back together. I can see how that could be useful if you're in the middle of staging one set of changes and then you want to stash the whole thing, but to me that's an extremely tiny window of time - most of the time, if I have staged changes and unstaged changes, they're meaningfully different pieces of change which I haven't finished separating out into the best atomic commits.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哥,最终变帅啦 2025-02-10 11:40:34

我对问题的第一部分表示同情,但我不认为有任何自动选择或配置。我认为最好的选择是不要那样做 - 也就是说,如果您要提供git命令,请明确地说出您的意思。这样,您就会知道会发生什么 - 因为您应该发生什么。 (出于同样的原因,我从不说git pull,我很少说git rebase 而无需说- 在上。)

同时,我想在第二部分中急剧推迟索赔:

破坏用户信息

嗯,没有。仅当您认为git commit破坏用户信息。 stash 在提交中保存用户信息(实际上是一对提交),并以使其易于恢复的方式保存。

混合成一个差异而没有任何区别

不正确的区别。该索引被保存为单独的提交。因此,可以完全恢复 git stash默认情况下,即未经跟踪和忽略的文件不会触摸的工作树。

储藏创建实际上是在于索引提交是当前作为父母的主管,而工人提交的提交具有索引提交和当前的父母。 (换句话说,存储的内容是合并提交!)您可以通过在藏匿条目上进行git log来查看此内容,并且您将看到Worktree comm准备恢复。

请注意,我是不是捍卫git Stash。这很奇怪,我通常会尝试避免它(尽管有时这是解决特定问题的一个很好的解决方案)。


附录:证明藏匿处可以恢复工作树和索引:

% git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   a.txt
    new file:   b.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   b.txt

% git stash
Saved working directory and index state WIP on main: bc7bf2c startover

% git stash apply stash@{0} --index
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   a.txt
    new file:   b.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   b.txt

I'm sympathetic with the first part of the question, but I don't believe there is any such automatic option or configuration. I think the best alternative is Don't Do That — that is, if you're going to give a Git command, say what you mean, explicitly. That way, you know what will happen — because you said what should happen. (For the same reason I never say git pull, and I rarely say git rebase without saying --onto.)

At the same time, I'd like to push back sharply on the claims in the second part:

destroys user information

Uh, no. Only if you think that git commit destroys user information. stash saves user information, in a commit (actually a pair of commits) — and saves it in a way that makes it easy to restore.

blended into one diff without any distinction

That is not true. The index is saved as a separate commit. Thus it is possible to restore exactly the situation as it was, both the index and the worktree (except, of course, for the parts of the worktree that git stash doesn't touch by default, namely untracked and ignored files).

The way stash creation actually works is that the index commit has current head as parent, and the worktree commit has the index commit and the current head as parents. (In other words, the stash’s content is a merge commit!) You can see this by doing git log on a stash entry, and you will see the worktree commit followed by the index commit, either or both ready for you to restore.

Note that I am not defending git stash. It's weird and I generally try to avoid it (though sometimes it is a good solution to a specific problem).


Addendum: Demonstration that a stash can restore both the work tree and index:

% git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   a.txt
    new file:   b.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   b.txt

% git stash
Saved working directory and index state WIP on main: bc7bf2c startover

% git stash apply stash@{0} --index
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   a.txt
    new file:   b.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
    modified:   b.txt
友谊不毕业 2025-02-10 11:40:34

根据文档,索引和工作树被很好地分成分离在Git Stash命令之后提交。

如果您担心的是要在git stash pop之后还原索引,我建议使用- index选项:git stash pop -index

别名可以使此选项的使用透明:(

git config alias.pop "stash pop --index"

如评论中提到的编辑别名)

According to the documentation, the index and the working tree are well separated into separated commits after the git stash command.

If your concern is to restore the index after a git stash pop I suggest using the --index option: git stash pop --index.

An alias can make transparent the use of this option:

git config alias.pop "stash pop --index"

(Edited the alias as mentioned in the comment)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文