git-lfs / git-lfs

Git extension for versioning large files
https://git-lfs.com
Other
12.94k stars 2.04k forks source link

Git LFS permits tracking of non-existent files #2323

Open WebDev64 opened 7 years ago

WebDev64 commented 7 years ago

Hello,

I have a Git repository residing within the following directory: C:/TFS/Sandbox/Sanbox. Now I created a new folder called 'Documentation' and dropped a file there 'DeploymentProcedure.docx'.

1) If I do $ git lfs track "Documentation/DeploymentProcedure.docx" it says "Tracking Documentation/DeploymentProcedure.docx"

=========================================

2) If I do $ git lfs track "Documentation/DeploymentProcedure1.docx" it says "Tracking Documentation/DeploymentProcedure1.docx"

but "DeploymentProcedure1.docx" does NOT exist.

=========================================

3) If I do $ git lfs track "DeploymentProcedure.docx" it says "Tracking DeploymentProcedure.docx"

But this time I did not specify "Documention/" prefix...and it still says Tracking...

=========================================

4) If I do $ git lfs track "Documentation/DeploymentProcedure1.docx" it says "Tracking DeploymentProcedure1.docx"

This time I also did not specify "Documention/" prefix...and DeploymentProcedure1.docx does NOT exist either, yet it still says Tracking...

=========================================

5) Also, if I do $ git lfs track "C:/TFS/Sandbox/Sandbox/Documentation/DeploymentProcedure.docx", it says: Tracking C:/TFS/Sandbox/Sandbox/Documentation/DeploymentProcedure.docx Error getting tracked files for "C:/TFS/Sandbox/Sandbox/Documentation/DeploymentProcedure.docx": exit status 128

Yet, in my .gitattributes I see this line: C:/TFS/Sandbox/Sandbox/Documentation/DeploymentProcedure.docx filter=lfs diff=lfs merge=lfs -text

==========================================

Git Attributes looks like this:

C:/TFS/Sandbox/Sandbox/Documentation/DeploymentProcedure.docx filter=lfs diff=lfs merge=lfs -text DeploymentProcedure.docx filter=lfs diff=lfs merge=lfs -text DeploymentProcedure1.docx filter=lfs diff=lfs merge=lfs -text Documentation/DeploymentProcedure1.docx filter=lfs diff=lfs merge=lfs -text Documentation/DeploymentProcedure.docx filter=lfs diff=lfs merge=lfs -text

...what a mess...

So a few questions: 1) Why am I able to add non-existing files to Git LFS? 2) Why even when a Git command errors out with 'exit status 128' is it still modifying .gitattributes (with incorrect information) ?

Thanks.

ttaylorr commented 7 years ago

Hi @WebDev64 thanks for opening this detailed issue! Here are some answers to your questions:

Why am I able to add non-existing files to Git LFS?

Git LFS does check for tracked files that match the pattern given to git-lfs-track(1) but only does so so that it can run os.Chtimes in order to mark it as "modified" so that Git will re-run it through LFS and properly track it. I think one thing that we could do to improve in this area would be to warn, or exit if the list of tracked files matching the given is empty.

Why even when a Git command errors out with 'exit status 128' is it still modifying .gitattributes (with incorrect information) ?

I'm not sure, this sounds like a bug to me.

WebDev64 commented 7 years ago

Hi ttaylorr, and thank you for the reply.

I am not sure if I understand what you are saying when you say:

Git LFS does check for tracked files that match the pattern given to git-lfs-track(1) but only does so so that it can run os.Chtimes in order to mark it as "modified" so that Git will re-run it through LFS and properly track it.

In point 2 above, "Documentation/DeploymentProcedure1.docx" did not exist, yet it still said it was ""Tracking Documentation/DeploymentProcedure1.docx"

In my mind, Git LFS should check the file path for existence of the file first, and abort if the file is not found before doing anything else.

Thanks.

ttaylorr commented 7 years ago

I am not sure if I understand what you are saying when you say:

Git LFS does check for tracked files that match the pattern given to git-lfs-track(1) but only does so so that it can run os.Chtimes in order to mark it as "modified" so that Git will re-run it through LFS and properly track it.

In point 2 above, "Documentation/DeploymentProcedure1.docx" did not exist, yet it still said it was ""Tracking Documentation/DeploymentProcedure1.docx"

Ah, sorry -- re-reading my response I realize that my wording is confusing. What I was discussing here is a technique that LFS uses for files that do exist. If a file matched by the pattern given to git-lfs-track(1) is tracked, then LFS touches that file so that Git can invoke the clean filter and convert it to LFS.

For patterns that don't match any files, this operation is a no-op, but I think you suggestion would involve something like:

matched := getTrackedFiles(pattern)
+if len(matched) == 0 {
+        ExitWithError(errors.New("fatal: no files matched pattern"))
+}

for _, match := range matched {
        os.Chtimes(match, ...)
}

I think if we adopt the above, we should also add a flag to git-lfs-track(1) that would allow the track command to exit cleanly even if no files are matched. Then again, we could probably avoid that and prefer that a user modifies their .gitattributes directly, in that case.