Skip to content

Make separate sub-tree-view vs just-git-tree classes or git.Tree runtime modes #1505

@castedo

Description

@castedo

This enhancement proposal is motivated by confusion in the behavior of subtrees. Issue #851 is one example. This stackoverflow question is another example.

As further example consider the following bash+python script behavior:

mkdir testrepo
cd testrepo
git init
mkdir 1
mkdir 2
echo hi > 1/hi.txt
cp 1/hi.txt 2/.
git add .
git commit -m 'test'

and then

import git

repo = git.Repo()
one = repo.head.commit.tree['1']
two = repo.head.commit.tree['2']
print("Same object?", one is two)
print("Same Python hash?", hash(one) == hash(two))
print("Same git hash?", one.hexsha == two.hexsha)
print("Equal?", one == two)
print("Same paths?", one.path == two.path)
print("hi.txt in one and two?", "hi.txt" in one, "hi.txt" in two)
print("1/hi.txt in one and two?", "1/hi.txt" in one, "1/hi.txt" in two)
print("2/hi.txt in one and two?", "2/hi.txt" in one, "2/hi.txt" in two)

which prints out:

Same object? False
Same Python hash? False
Same git hash? True
Equal? True
Same paths? False
hi.txt in one and two? False False
1/hi.txt in one and two? True False
2/hi.txt in one and two? False True

What I think most people would expect is that "hi.txt" is contained in both one and two and 1/hi.txt and 2/hi.txt are contained in neither one nor two. This is essentially the same issue noted in #851.

I think most people would also not expect these Tree objects to be ==-equal but then also have a property path that has different values.

It seems to me the fundamental problem is that the Tree class is trying to behave like two things that are different things:

  • a git tree, in the git object database
  • a subdirectory/subtree in a git index

In the sample above, one and two are the same git tree but they are not the same subdirectory added to a git index. A git tree does not have a path but a subdirectory added to a git index does. The current __contain__ logic is kind-of-OK if the objects are subdirectories added to a git index, but make no sense for a git tree.

Due to backwards compatibility, this seems a challenging issue to address. I don't know the code and backwards compatibility situation well enough to make any recommendations. But I'm happy to help. I can suggest some different approaches, but I figure it's best to seek your @Byron input on this first.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions