1

I want to know how to pull with rebase from the origin, and if the files have conflicts I want to keep the latest modified file.

Is there a way in git to get the modified date of each file in a commit or just the commit date? Or is there a way to list the files with differences from your local branch vs the origin and tell on which side is the latest modified file?

Example Scenario:

origin/mybranch:
    - File A (modified today)
    - File B (modified yesterday)

local/mybranch:
    - File A (modified yesterday)
    - File B (modified today)

If I git pull --rebase I want to keep the latest versions of File A and File B.

I'm using GitPython to manipulate the repository, so I need an automatic way of resolving any conflicts using this criteria (keep the changes from the latest modified file).

  • This contradicts the point of git. If someone added "Hello" to A yesterday, and someone else added "World" today, why wouldn't you want both changes? Things like dropbox and the like are more suited for this - where last change is always applied. GIT is specifically used to merge changes from different team members -- beyond just a version control. – kabanus May 25 '18 at 18:43
  • I'll add GIT doesn't really care about "time" as it does about the tree structure. If you have to do this I think the solution will be manual. – kabanus May 25 '18 at 18:46
  • I'm adding git to a web platform to have the history of changes made to the code in that platform (the platform doesn't have any history or anything and is one instance for multiple users so the code will always reflect the latest changes even if that means overriding stuff). I do need the history of changes, but when there are merge conflicts I need an automatic way of solving them, and that is the criteria described above, since that is what would reflect the current state of the code in the web platform. All this is done using a web extension and a server running gitpython for the repo. – Haibrayn González May 25 '18 at 21:29
  • If the git is only sitting on the server, so everyone is using the same repo, that would be exactly what you want no? Always consider two users editing at the same time, and saving minutes apart - probably you want to stop the second one, and let him see the differences before overwriting. – kabanus May 26 '18 at 13:44
  • Actually right now the server runs on each developer machine (similar to how the Zotero web extension works), due to some corporate credentials issue. Maybe this won't be an issue if the server is centralized. – Haibrayn González May 29 '18 at 00:16

1 Answers1

1

First of all there's no such merge strategy as "favor the latest change by the commit date" out of the box. Here's the list of supported strategies

From this list it seems that "recursive" strategy with "ours/theirs" option might solve some part of your example case:

Because you want to use "rebase", it means that it would take "origin/mybranch" as the base of your merge, and then try to apply your new commits on top of it.

Then there are 2 cases: either your change happened later - in this case it will apply cleanly, or your change happened earlier - and in this case you say that you want to apply their version (that is --strategy-option "ours" or "theirs", I think it is "ours" for rebase, this is confusing...).

The problem with this is that if your change happened today, and their change happened yesterday, but you forgot to sync in the morning, then even that your change happened later (by commit date) it will still produce a conflict, and be resolved inappropriately to their version instead of yours.

If that's not exactly what you want, you can probably write a custom automatic merge tool that when presented with a conflict is going to find out commit dates that caused it, and choose ours/theirs depending on which commit date is latest.

Then you can write a script that applies rebase and your custom merge tool on each conflict.

Brief logic of such a merge tool

  1. Given a conflicting file name, and knowing remote and local branch names, you can find out a commit at which this file was last modified for each branch - see How do I find the most recent git commit that modified a file?

  2. Then get dates of those 2 commits and compare them

  3. and take appropriate merge decision: copy over LOCAL or REMOTE.

battlmonstr
  • 5,841
  • 1
  • 23
  • 33
  • Thanks for the answer. Looks like you don't even need to know the branch names, since you can look for the commits that modified each conflicting file and checkout the file from the most recent sha right? – Haibrayn González May 25 '18 at 21:45
  • You need a branch name to be able to search commits in it, but it's not a problem, you can pass it to your custom merge script as an argument, or have a default that your always merge your current branch to its tracking branch, and get it like that. – battlmonstr May 26 '18 at 14:56
  • will `git log origin/branch-name --date-order -1 --date=iso8601 --format='%h %cd' -- conflict_file.txt` give the sha of the latest commit on the file in the actual remotes or just your local copy of the remotes? – Haibrayn González Jun 01 '18 at 22:12
  • Yes, just local copy. Git always works on a local copy. You have "git fetch" to download state of the remote copy into the local copy. – battlmonstr Jun 02 '18 at 09:50