Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork937
Description
Environment:
- GitPython version: 3.1.44
- Git version: git version 2.42.0.windows.2
- Python version: 3.12.0
- Operating System: Windows 11 Pro 24H2 26100.3775
Description:
When initializing a new repository, adding a file to the index, writing the index to disk, and then explicitly reading the index back, a subsequent call torepo.index.diff(None)
incorrectly returns an emptyDiffIndex
(an empty list). This occurs even though an externalgit status --porcelain
command correctly shows the file as added to the index (stage 'A').
This suggests that the in-memory state of theIndexFile
object is not correctly reflecting the on-disk state for thediff(None)
operation under these specific circumstances, even after an explicitrepo.index.read()
.
Steps to Reproduce:
importosimporttempfileimportshutilfromgitimportRepo,IndexFile,Actor# Setup a temporary directory for the new repositoryrepo_dir=tempfile.mkdtemp(prefix="test_gitpython_index_issue_")try:# 1. Initialize a new repositoryrepo=Repo.init(repo_dir)print(f"Repository initialized at:{repo_dir}")print(f"Is bare:{repo.bare}")# Should be False# 2. Create and add a new file (.gitkeep in this example)gitkeep_path=os.path.join(repo.working_tree_dir,".gitkeep")withopen(gitkeep_path,'w')asf:f.write("# Initial file\n")print(f".gitkeep created at:{gitkeep_path}")index=repo.indexindex.add([".gitkeep"])# Relative path to repo rootprint(f"Added '.gitkeep' to index object in memory.")# 3. Write the index to diskindex.write()print(f"Index written to disk at:{index.path}")assertos.path.exists(index.path),"Index file should exist on disk"# 4. (Optional but good for verification) Check with external git statusstatus_output=repo.git.status(porcelain=True)print(f"git status --porcelain output: '{status_output}'")assert"A .gitkeep"instatus_outputor"?? .gitkeep"instatus_output# Should be 'A ' after add+write# 5. Explicitly re-read the index (or create a new IndexFile instance)# This step is crucial to the bug demonstration.index.read()# Force re-read of the IndexFile instance# Alternatively: index = IndexFile(repo) # Create new instance, should also read from diskprint(f"Index explicitly re-read. Number of entries:{len(index.entries)}")assertlen(index.entries)>0,"Index should have entries after add/write/read"# 6. Perform a diff of the index against an empty tree (None)# This simulates what happens before an initial commit to see staged changes.diff_against_empty_tree=index.diff(None)print(f"index.diff(None) result:{diff_against_empty_tree}")print(f"Type of result:{type(diff_against_empty_tree)}")foritem_diffindiff_against_empty_tree:print(f" Diff item: a_path={item_diff.a_path}, b_path={item_diff.b_path}, change_type={item_diff.change_type}, new_file={item_diff.new_file}")# Expected behavior:# index.diff(None) should return a DiffIndex containing one Diff object# representing the newly added '.gitkeep' file (change_type 'A').assertlen(diff_against_empty_tree)==1, \f"Expected 1 diff item, got{len(diff_against_empty_tree)}. Entries:{index.entries}"diff_item=diff_against_empty_tree[0]assertdiff_item.change_type=='A', \f"Expected change_type 'A', got '{diff_item.change_type}'"assertdiff_item.b_path==".gitkeep", \f"Expected b_path '.gitkeep', got '{diff_item.b_path}'"exceptExceptionase:print(f"An error occurred:{e}")raisefinally:# Clean up the temporary directory# shutil.rmtree(repo_dir)# print(f"Cleaned up temp directory: {repo_dir}")pass# To run this reproducer:# 1. Save as a .py file.# 2. Ensure GitPython is installed.# 3. Run `python your_file_name.py`
Actual Behavior:repo.index.diff(None)
returns an emptyDiffIndex
(i.e.,[]
).
Expected Behavior:repo.index.diff(None)
should return aDiffIndex
containing oneDiff
object for.gitkeep
withchange_type='A'
,new_file=True
,a_path=None
, andb_path='.gitkeep'
.
Additional Context:
- This issue prevents correctly determining staged changes for an initial commit using
index.diff(None)
. - The
index.entries
dictionarydoes seem to reflect the added file correctly afterindex.read()
. - The
repo.git.status(porcelain=True)
command correctly shows the file as staged for addition (A .gitkeep
). - The problem seems specific to how
IndexFile.diff(None)
interprets theIndexFile
's state after this sequence of operations in a new repositorybefore the first commit. Diffing againstHEAD
(once a commit exists) or other trees might behave differently.