-
-
Notifications
You must be signed in to change notification settings - Fork 933
GitPython can stage changes for commit that git won't commit #1185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Otherwise, `git commit` will not commit them, even though they are visible to `git status`. See gitpython-developers/GitPython#1185
Further investigation shows the Method
Method
The differences in bytes 0x0C – 0x1B is a difference in file modification times and doesn't seem to be important. The critical difference is the insertion in the
And, lo and behold, changing |
This removes some cached tree data that should be invalidated by our changes to the index (assuming we've added/updated things). Otherwise, `git commit` will not commit changes, even though they are visible to `git status`. See gitpython-developers/GitPython#1185
First off, let me thank you for sharing this detective story, I am amazed by the skill that was needed to figure this one out! It looks like simply maintaining the extension as is isn't the right way of doing things, maybe because it tells Probably it would have been wise to ignore extension data by default, but changing it now would be a breaking change so probably won't be doable either. Maybe there can be a compromise and GitPython could detect the Do you think that could work or do you have other ideas? |
First, thank you for the kind comment — would that everyone put such thought into their replies! I don't know much about git index extensions, so take these opinions with a grain of salt. It seems reasonable to try to preserve the extension data more; right now I agree that parsing the extension data and removing or invalidating the At this point, there are two approaches that I think we could take:
In addition, we'd need to decide if, after we get invalidation working, we should have I'm happy to work on any of this! (Also: I'm going to edit the minimal working example to annotate how each piece of it contributes to the weird behavior.) |
On further looking, it seems we might also need to:
|
My apologies for the late reply. Here is my commentary :D
Furthermore this looks like it would fix the bug seen if the
That should be as simple as removing
Yes, definitely!
In order to enable multi-threaded parsing of the cache, I expect various blocks of offsets there which should match the amount of entries in the index. At first, this one should definitely be removed if the amount of entries changed. Initially it should be easiest to unconditionally remove it. To me it looks like only the In any case, I thank you for investigating this (I learned a lot), and will be happy to see any PR :). |
My thought for why we might need to worry about Also, this comment seems to imply that we can drop any all-caps extension data, though I'd like to be a bit more polite about it when that's not too hard to do. I'll get started on a PR shortly! |
That's true actually - I guess my hope was that with untracked files out of sync there may be no malfunction, but why risk it. It seems easy enough to drop data once a certain code path was encountered.
I love this attitude! Mine seems a bit sloppy at times so I am happy to see this countered :).
🎉🙏 |
Steps to reproduce:
IndexFile
object.add()
on that object.write()
git
binary on the system (instead of using.commit()
on theIndexFile
object)Here is a minimal working example:
I've reproduced this on both Python 3.9 and 3.8, git 2.30, gitpython 3.0.8 and 3.1.13 across several machines, both Windows and Linux.
It seems the only difference between the calls to
r.git.commit
is thatr.index.add
andr.index.write
are calls made to two differentIndexFile
objects. Using the same object for both calls results in the changes not being committed.Added twists:
our_index.write_tree()
and usegit commit-tree
, the changes staged get committed.our_index.commit()
, the changes staged get committed.r.active_branch.checkout()
, the changes staged get committed.This is truly bewildering to me. I'm happy to try to debug more, but any sort of speculation on where to start would be helpful!
The text was updated successfully, but these errors were encountered: