dulwich icon indicating copy to clipboard operation
dulwich copied to clipboard

porcelain.add no longer works when run within a directory ignored by a gitignore

Open Julian opened this issue 6 years ago • 4 comments

porcelain.add appears to use os.path.relpath to try to calculate relative paths relative to a repo root, but that's not what os.path.relpath does. E.g.:

⊙  cd /tmp; python -c 'import os.path; print os.path.relpath("foo", "/foo/bar")'; cd ~; python -c 'import os.path; print os.path.relpath("foo", "/foo/bar")'                                                                                                                                                                                                Julian@Macnetic
../../private/tmp/foo
../../Users/Julian/foo

so if previously something was running porcelain.add(repo=somerepo, paths=["somepath"]) (and since repo.paths are absolute), the file is now ignored incorrectly if cwd happens to be a directory ignored by gitignore.

Julian avatar Aug 15 '17 21:08 Julian

The new behaviour is intentional, since it matches the behaviour of the git command line tool. Relative paths are interpreted relative to PWD,but need to be relative to the root of the repository when passed into other Dulwich functions.

However, paths outside of the repository are currently silently ignored, but should probably trigger an exception.

I'll also add a clear warning in NEWS.

jelmer avatar Aug 18 '17 10:08 jelmer

Still have to play around here, but it seems a bit odd to me to be worrying about PWD -- that makes sense for a CLI, but for a library it's unnecessary global state to deal with.

Some other things besides add are giving us trouble in our unit tests now, so some other behavior seems to have changed as well (particularly in porcelain.status as well, where lots of things are being marked as "untracked" now even though they're tracked, so something's getting confused about a relative path).

Realize that's not enough to go on, will have to dig in further to decypher whether it's our fault or not here.

Julian avatar Aug 31 '17 13:08 Julian

porcelain is supposed to mostly resemble the cli.

one option would be to require paths are always absolute.

jelmer avatar Nov 05 '17 17:11 jelmer

@jelmer - I think I may be hitting this as well, and porcelain is not acting like the git CLI.

I have a global ~/.gitignore file, with the following line:

tmp/

Now, if I run this python code:

# Initialize a git repo in /tmp dir
repo = porcelain.init("/tmp/my-repo")

# Add a file to the repo
f = open('/tmp/my-repo/file.txt', 'w')
f.write('some content')
f.close()

# get the repo status
status = porcelain.status(repo)

assert status.untracked == []  # true

So porcelain does not detect any files within my repo. However, if I run a git status from repo, the untracked file does show up:

$ cd /tmp/my-repo
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	file.txt

If I empty my .gitignore, porcelain works as expected.

eschwartz avatar Jan 18 '19 19:01 eschwartz