git-store-meta icon indicating copy to clipboard operation
git-store-meta copied to clipboard

automatically preserve mtime during merge

Open DominikFickenwirth opened this issue 2 years ago • 11 comments

My current method

During merges, I want to preserve the mtime for all files that only changed in one branch. In this issue I will focus on the mtime field, but this issue might affect other fields as well.

Right now, I do git checkout --ours -- .git_store_meta during the merge. After manually completing the merge, git-store-meta.pl --update will do the rest. This preserves the datetime of files which only changed in "our" branch, but not those of "their" branch. I elaborate below.

How do you guys handle merges of file dates at the moment? Just do it manually?

Merging

Let's say, I'm merging their-branch into our-branch. When the merge succeeds automatically, everything works as expected. In this case, .git_store_meta got successfully merged like any other file, which is what we want. The pre-commit hook does not get called in this case, so the merged version of .git_store_meta will be committed.

Problems only arise, when the merge stops before creating the merge commit. After completing the merge manually with git merge --continue or git commit, the pre-commit hook is called. Generally, this is a good thing: Files which were changed in both branches should get the current datetime, since the merge actually changed the contents of the file.

There are a few cases however, where we want to preserve the datetime of their-branch:

  • When a file was created / changed in their-branch only, but not in our-branch
  • When we resolve a conflicting file with git checkout --theirs -- filename.

Note, that the datetime of our-branch already get preserved:

  • When a file was created / changed in our-branch only, but not in their-branch.
  • When we resolve a conflicting file by git checkout --ours -- filename. For this to work, use "my version" above.

Rebasing

Let's say, I'm rebasing branch-A on branch-B. If I understand rebasing correctly, this is kind of equivalent to the following:

  1. create a new branch branch-A2 based on branch-B
  2. merge every commit of branch-A into branch-A2 one by one. So, having a solution to the merging problem should solve rebasing as well, even though we'd have to call git-store-meta.pl ourselves (as rebasing does not call our hooks).
  3. reset branch-A to branch-A2 and delete the latter

Thus, rebasing internally uses the same mechanism as merging. Therefore, solving this issue for merges should solve it for rebases as well.

Solution suggestion

I see two options, how we could make this work:

  1. A separate command that we need to run manually during a merge or rebase
  2. Adding some kind of check inside the --store and --update procedures, whether we are in the process of merging, rebasing, or just committing.

DominikFickenwirth avatar Mar 15 '22 18:03 DominikFickenwirth