{"thread":{"id":"61780","subject":"bug: `git pull` does not clean up after itself if it fails","startedAt":"2024-07-15T11:25:17Z","lastAt":"2024-07-17T09:12:03Z","messageCount":3,"participants":["Nikolai Zaki","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"498721","messageId":"0cc13c53-1d8d-4501-89f2-e8329bc95485@charite.de","threadId":"61780","inReplyTo":null,"subject":"bug: `git pull` does not clean up after itself if it fails","fromName":"Nikolai Zaki","fromEmail":"nikolai-waleed.zaki@charite.de","sentAt":"2024-07-15T11:19:32Z","receivedAt":"2024-07-15T11:25:17Z","isPatch":false,"sender":{"key":"nikolai-waleed.zaki@charite.de","avatar":null},"body":"What did you do before the bug happened? (Steps to reproduce your issue)\nIn your local repo have a directory that you cannot write to.\nPull from a remote that has changes/new files in that directory.\n\nWhat did you expect to happen? (Expected behavior)\nThe pull fails and the local repo in the same state as before.\n\nWhat happened instead? (Actual behavior)\nAll changes to writeable files are applied and all new files in \nwriteable dirs are added.\nThe local HEAD however remained the same.\n\nWhat's different between what you expected and what actually happened?\nA failed `git pull` inadvertently creates changes and untracked files.\n\nAnything else you want to add:\nI created this bugreport on my local machine, but I first noticed this \non git version 2.25.1 under Ubuntu (uname: Linux s-c05-mvi-civdb \n5.4.0-174-generic #193-Ubuntu SMP Thu Mar 7 14:29:28 UTC 2024 x86_64 \nx86_64 x86_64 GNU/Linux)\n\n[System Info]\ngit version:\ngit version 2.45.2\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nuname: Linux 6.9.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 28 Jun 2024 \n04:32:50 +0000 x86_64\ncompiler info: gnuc: 14.1\nlibc info: glibc: 2.39\n$SHELL (typically, interactive shell): /bin/zsh\n\n-- \nBest,\nNikolai\n"},{"id":"498814","messageId":"20240717055549.GD547635@coredump.intra.peff.net","threadId":"61780","inReplyTo":"0cc13c53-1d8d-4501-89f2-e8329bc95485@charite.de","subject":"Re: bug: `git pull` does not clean up after itself if it fails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2024-07-17T05:55:49Z","receivedAt":"2024-07-17T05:55:50Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jul 15, 2024 at 01:19:32PM +0200, Nikolai Zaki wrote:\n\n> What did you do before the bug happened? (Steps to reproduce your issue)\n> In your local repo have a directory that you cannot write to.\n> Pull from a remote that has changes/new files in that directory.\n> \n> What did you expect to happen? (Expected behavior)\n> The pull fails and the local repo in the same state as before.\n> \n> What happened instead? (Actual behavior)\n> All changes to writeable files are applied and all new files in writeable\n> dirs are added.\n> The local HEAD however remained the same.\n> \n> What's different between what you expected and what actually happened?\n> A failed `git pull` inadvertently creates changes and untracked files.\n\nA pull is basically fetch followed by merge. So I'd expect us to fail in\nthe merge step, at which point pull would generally leave the state\nas-is, because merge failures tend to be conflicts.\n\nSo I guess doing what you expect would require a merge which hits a\nnon-conflict error (like an unwriteable directory) to clean up after\nitself. That's probably not impossible, but it may be rather tricky,\nespecially if we are concerned about unrelated changes in the working\ntree.\n\n-Peff\n"},{"id":"498820","messageId":"0a20d825-3430-4397-962c-a6b5e94d70eb@charite.de","threadId":"61780","inReplyTo":"20240717055549.GD547635@coredump.intra.peff.net","subject":"Re: [ext] Re: bug: `git pull` does not clean up after itself if it fails","fromName":"Nikolai Zaki","fromEmail":"nikolai-waleed.zaki@charite.de","sentAt":"2024-07-17T09:11:54Z","receivedAt":"2024-07-17T09:12:03Z","isPatch":false,"sender":{"key":"nikolai-waleed.zaki@charite.de","avatar":null},"body":"Hi Peff,\n\nthanks for your reply. You're right, the problem happens during merge.\n\nSince merge already aborts if the index doesn't match HEAD though, \ncouldn't it be as simple as saving the state of the worktree and then \neither restoring it in case of failure or applying the diff in case of \nsuccess?\n\nIn terms of git commands I think the following would work:\n\nWhen `git merge` is run first run `git stash --all` then `git merge` as \nusual.\n\nIf there are non-conflict errors: `git checkout .` and `git clean -f;\n\nIf there are no errors `git stash pop`.\n\n\nOn 7/17/24 07:55, Jeff King wrote:\n> On Mon, Jul 15, 2024 at 01:19:32PM +0200, Nikolai Zaki wrote:\n>\n>> What did you do before the bug happened? (Steps to reproduce your issue)\n>> In your local repo have a directory that you cannot write to.\n>> Pull from a remote that has changes/new files in that directory.\n>>\n>> What did you expect to happen? (Expected behavior)\n>> The pull fails and the local repo in the same state as before.\n>>\n>> What happened instead? (Actual behavior)\n>> All changes to writeable files are applied and all new files in writeable\n>> dirs are added.\n>> The local HEAD however remained the same.\n>>\n>> What's different between what you expected and what actually happened?\n>> A failed `git pull` inadvertently creates changes and untracked files.\n> A pull is basically fetch followed by merge. So I'd expect us to fail in\n> the merge step, at which point pull would generally leave the state\n> as-is, because merge failures tend to be conflicts.\n>\n> So I guess doing what you expect would require a merge which hits a\n> non-conflict error (like an unwriteable directory) to clean up after\n> itself. That's probably not impossible, but it may be rather tricky,\n> especially if we are concerned about unrelated changes in the working\n> tree.\n>\n> -Peff\n-- \nBest,\nNikolai\n"}]}