copier-org / copier

Library and command-line utility for rendering projects templates.
https://readthedocs.org/projects/copier/
MIT License
1.82k stars 170 forks source link

uncommited changes only used in template repos without tags #879

Closed FlorianLudwig closed 1 year ago

FlorianLudwig commented 1 year ago

Describe the problem According to this thread: https://github.com/copier-org/copier/discussions/743 copier is supposed to use uncommited changes by default. But it only does so when no tags exist in the template repository.

To Reproduce

mkdir template
cd template
echo "Hi" > test.txt
git init 
git add .
git commit -a -m "1"
git tag v0.0.1
echo "Hi2" > test.txt
copier copy . /tmp/foo
cat /tmp/foo/test.txt

The result is Hi

Expected behavior Hi2

Environment

yajo commented 1 year ago

The reproduce steps are wrong. Copier is doing what it is supposed to do AFAICS.

Could you try with this command instead?

copier -r HEAD copy . /tmp/foo
FlorianLudwig commented 1 year ago

@yajo

mkdir template
cd template
echo "Hi" > test.txt
git init 
git add .
git commit -a -m "1"
git tag v0.0.1
echo "Hi2" > test.txt
copier -r HEAD copy . /tmp/foo
cat /tmp/foo/test.txt

results in:

Hi

which acording to your comment here: https://github.com/copier-org/copier/discussions/743#discussioncomment-3453570 should be Hi2 to my understanding

yajo commented 1 year ago

Thanks, that looks like a bug then.

FlorianLudwig commented 1 year ago

@yajo After thinking about it again today, I think -r HEAD should not use dirty changes.

-r HEAD is telling copier explicitly to use the vcs HEAD which means "latest commit" in git. So using uncommited changes would be unexpected.

Currently the existence of tags in the git repo changing the behavior is really surprising so I would love to see it gone.

Some options how to design the behavior:

1. By default for local path use checkout

2. By default for local path use newest git commit

Now we would need a way to tell copier to include dirty changes:

2.1 special -r tag

It should be something that is not already used terminology in git, like HEAD. So maybe CHECKOUT or CURRENT. While unlikely it brings the possibility to have a name clash with a branch.

2.2 separate flag in addition to -r

Instead of using -r at all when wanting to use the current directory "as is" have a new flag, e.g. --allow-dirty. When used in combination with -r it should abort with an error.


Personally I prefer 1 or 2.2 and not overloading the -r option.

yajo commented 1 year ago

1 wouldn't be enough because, if there are any dirty changes, those wouldn't be taken into account by the update algorithm.

However, 2.2 seems a good option to me. I'd call it --dirty-head, so when this flag is true, then HEAD does the magic; otherwise, it just behaves as a predictable HEAD would behave in normal git.