1

My ref HEAD points the branch foo, that points to the commit 123abc; and I have some staged work.

How to git commit that work, moving the HEAD to the newly created commit, but without advancing the branch?

(hence: leaving foo point to 123abc)

Is it possible to do it with a single git command?

Kamafeather
  • 5,651
  • 10
  • 44
  • 74
  • [Quentin's answer](https://stackoverflow.com/a/61475780/1256452) is fine, but out of curiosity, *why* do you want to do this? (It's more typical to do `git checkout -b newbranch; git commit` so that the name `newbranch` remembers the new commit for you.) – torek Apr 28 '20 at 12:15
  • That's exactly what I do **not** want. I've ideated a workflow for myself, where I want to be able to make a *"backup commit"* on my development fork, but not on the branch itself. After the detached commit, I just `git tag BAK-change-foobar-schema` and push it. – This way I can backup my current work **without** making my development branch "dirty" (and without having to `push force` over it, after `git-reset`ting the backup & continuing & committing the definitive commit). – So I know that my branch has just "real" `commit`ments and doesn't contain WIP code. – Kamafeather Apr 28 '20 at 12:30
  • Ah: you want to commit so that you can tag the commit (use a tag to remember the hash ID). That's fine, but note that you can also `git checkout -b temp; git commit; git tag ...; git checkout master; git branch -D temp` for instance. Your branch names are *yours* so you can do anything you like with them. The detach-and-commit-and-tag is short and useful, though; it's the kind of thing that you can put in a script, or a Git alias. – torek Apr 28 '20 at 12:33
  • 1
    (Everyone I know just uses a private development branch, though. There's a pretty good reason to avoid tag names in a *shared* repository: the tag names get copied to other clones, whereas the branch names just become remote-tracking names that people can ignore. Obviously this doesn't apply to a *private* repository.) – torek Apr 28 '20 at 12:33
  • Yes, but I don't like the maintenance of that `temp` branch (I tend to forget dirt around), the `--detach` option helps with that; and I usually try to avoid aliases (that I don't get, for example, on remote systems). – The way I see that, this commit should just not be in the branch in the first place (or on a branch at all); it's just a backup: a commit that stores code but should have no historical meaning. – Kamafeather Apr 28 '20 at 12:37
  • Again, yes, you are right. This is indeed contextual to a fork/private repository that I can play with, push personal/dirty tags and eventually rewrite history without worrying of affecting other devs. – When the branch is "more ready and stable" then I push it in the real branch on the shared repository. Before that moment, I can rewrite wildly as I need – Kamafeather Apr 28 '20 at 12:41

3 Answers3

3

Simply detach, then commit:

git checkout --detach
git commit -m "Commit as usual"
Quentin
  • 58,778
  • 7
  • 120
  • 175
1

If HEAD is directly pointing to commit 123abc, it's already on detached HEAD state instead of on foo. git commit will create a new commit and move HEAD to the new commit, leaving foo unmoved.

If HEAD points at refs/heads/foo and refs/heads/foo points at 123abc, you can run git checkout 123abc and then make the commit.

ElpieKay
  • 19,185
  • 5
  • 22
  • 36
  • yes, you are right, I should fix the question and mean that `HEAD` points to the branch `foo`, rather than the commit itself directly. – Kamafeather Apr 28 '20 at 08:30
  • Good answer, but I chose the one from @Quentin since it allows to do what I ask without having to know the `refs` or commit SHA. Thank you tho! – Kamafeather Apr 28 '20 at 08:43
0

You could just commit and then do a reset:

# from foo branch
git commit -m 'your work here'
git reset --soft HEAD~1

This would move the HEAD pointer back one commit to 123abc, but would also stage all the work in that commit.

There are other types of reset (mixed, hard), which do variants of the above. Without knowing your end goal, it isn't clear what kind of reset you should use. In general, though, moving the HEAD back one commit is something you would do if you wanted to rewrite the prior HEAD commit.

Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
  • Yes, that's legit, and is what I usually do, thanks. In this case I was specifically requesting about committing *without advancing the branch*. I was looking for what's described from @Quentin 's answer. – Kamafeather Apr 28 '20 at 08:35