6

Is there a way to group commits in Git?? I had a story to create a user. I created, file by file and committed each file individually. And pushed it to the github repo. Now I want to group all the previous commits, say under the label "User Creation" so that I can refer to all of them all together.

I don't want to collate so squash doesn't work.

This SO question has similar requirements, but while naming the commits, the OP had used @some_label. I haven't used any such label too.

Is there any way to do this. If yes, how?

Community
  • 1
  • 1
inquisitive
  • 3,738
  • 6
  • 30
  • 56
  • 3
    Follow my answer here to a similar problem http://stackoverflow.com/questions/31668794/squash-all-your-commits-in-one-before-a-pull-request-in-github/31669260#31669260 – EnriMR Sep 03 '15 at 15:50
  • The very process you wish to happen *is* squashing. Even in interactive rebase, that's still squashing the commits together. Why don't you want that? – Makoto Sep 03 '15 at 15:52
  • 1
    you have misunderstood my question. I want the previous commits to still be there, but just group them. – inquisitive Sep 03 '15 at 15:53
  • 2
    @Makoto squashing replaces several commits with a single commit. That seems different from wanting to refer to a set of separate commits. – Caleb Sep 03 '15 at 15:54
  • 1
    @Caleb: Yes, that is different. I'll retract that dupe vote since it doesn't seem like that's what they want. – Makoto Sep 03 '15 at 15:55
  • The only "labels" you can add on commits are tags. You could tag every single commit and use a common prefix for each group of commits. But that's not very practical. – Sébastien Dawans Sep 03 '15 at 15:56
  • 2
    @Inquisitive How do you plan to *use* these groups? For example, do you need to be able to select only the commits in the group? Or do you only need to be able to talk about certain sets of commits? Normally, squashing is the right answer if you have a collection of commits that are all needed for a given feature, and if you need some capability beyond that, perhaps you could explain why. Why do your user creation commits need to exist individually, for example? – Caleb Sep 03 '15 at 16:01
  • 1
    This is one such assignment where our commits and commit messages will also be read and evaluated by the our teachers. So I still need the old messages. I want to group them for my clarity that I'm done with one story and we will get many such stories. and I was just curious if any such thing do exist in git. – inquisitive Sep 03 '15 at 16:05
  • @Caleb This is useful for having detailed iterative commits that can be easily git-bisected to find regressions, but at the same time having an organized git history that would be relatively easy to browse. – maratbn Jul 03 '21 at 22:32

2 Answers2

10

Create your commits on a branch, and merge the branch back into master using --no-ff.

To do this retroactively, assuming you have no more commits after the user-creation commits:

  1. Create a branch (git branch user-creation) on the latest commit.
  2. Move the master branch (which I assume you already have checked out) back to the last commit before the user-creation commits (git reset --hard OLD-COMMIT-SHA).
  3. Merge the user-creation branch into master (git merge --no-ff user-creation).
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • That is a nice approach to do, but I have already pushed commits. Without creating the branch. – inquisitive Sep 03 '15 at 16:02
  • I was writing an answer suggesting this as well, so retracting it. If you've already pushed the commits and are OK to rewrite the history then just fix it and push -f – Sébastien Dawans Sep 03 '15 at 16:03
  • 3
    I've added instructions for retroactively creating and merging the branch. – rob mayoff Sep 03 '15 at 16:03
  • Indeed, `git mrege --no-ff` appears to be the best solution for this problem so far, also see https://stackoverflow.com/questions/9069061/what-is-the-difference-between-git-merge-and-git-merge-no-ff – maratbn Jul 03 '21 at 22:33
3

If you don't want to squash, just do a rebase and modify the commits adding the "@fancy_label", then follow the instructions in your link:

You could use post-commit hooks in your repository to achieve this effect. Briefly:

  1. You commit with message, containing special label (example: @fancy_label)
  2. post-commit hook parsing your commit message and detects this @fancy_label (and other labels)
  3. post-commit hook after this adds this commit to list of commits for each label and saves it to persistent storage (to plain files, or even database)

This persistent storage could be personal (non-committable in folder .git) or committable (included in project).

And you need to make git aliases to make searching and listing of this commits by their respective labels easier.