{"thread":{"id":"4290","subject":"[PATCH] Don't write directly to a make target ($@).","startedAt":"2006-05-25T13:32:11Z","lastAt":"2006-05-25T16:52:01Z","messageCount":6,"participants":["Jim Meyering","Junio C Hamano","Timo Hirvonen"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"20682","messageId":"87hd3e5ixw.fsf@rho.meyering.net","threadId":"4290","inReplyTo":null,"subject":"[PATCH] Don't write directly to a make target ($@).","fromName":"Jim Meyering","fromEmail":"jim@meyering.net","sentAt":"2006-05-25T13:32:11Z","receivedAt":"2006-05-25T13:32:11Z","isPatch":true,"sender":{"key":"jim@meyering.net","avatar":"https://avatars.githubusercontent.com/u/710630?v=4"},"body":"Otherwise, if make is suspended, or killed with prejudice, or if the\nsystem crashes, you could be left with an up-to-date, yet corrupt,\ngenerated file.\n\n---\n\n Makefile |   34 ++++++++++++++++++++--------------\n 1 files changed, 20 insertions(+), 14 deletions(-)\n\n59fd5cb51824364100cacd92f1ca4674853a13a8\ndiff --git a/Makefile b/Makefile\nindex dbf19c6..3af3187 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h\n \trm -f $@ && ln git$X $@\n \n common-cmds.h: Documentation/git-*.txt\n-\t./generate-cmdlist.sh > $@\n+\t./generate-cmdlist.sh > t$@\n+\tmv t$@ $@\n \n $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh\n-\trm -f $@\n+\trm -f $@ t$@\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t    -e 's/@@NO_CURL@@/$(NO_CURL)/g' \\\n \t    -e 's/@@NO_PYTHON@@/$(NO_PYTHON)/g' \\\n-\t    $@.sh >$@\n-\tchmod +x $@\n+\t    $@.sh >t$@\n+\tchmod +x t$@\n+\tmv t$@ $@\n \n $(patsubst %.perl,%,$(SCRIPT_PERL)) : % : %.perl\n-\trm -f $@\n+\trm -f $@ t$@\n \tsed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n-\t    $@.perl >$@\n-\tchmod +x $@\n+\t    $@.perl >t$@\n+\tchmod +x t$@\n+\tmv t$@ $@\n \n $(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py\n-\trm -f $@\n+\trm -f $@ t$@\n \tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n \t    -e 's|@@GIT_PYTHON_PATH@@|$(GIT_PYTHON_DIR_SQ)|g' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n-\t    $@.py >$@\n-\tchmod +x $@\n+\t    $@.py >t$@\n+\tchmod +x t$@\n+\tmv t$@ $@\n \n git-cherry-pick: git-revert\n-\tcp $< $@\n+\tcp $< t$@\n+\tmv t$@ $@\n \n git-status: git-commit\n-\tcp $< $@\n+\tcp $< t$@\n+\tmv t$@ $@\n \n # These can record GIT_VERSION\n git$X git.spec \\\n@@ -653,7 +659,8 @@ install-doc:\n ### Maintainer's dist rules\n \n git.spec: git.spec.in\n-\tsed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@\n+\tsed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > t$@\n+\tmv t$@ $@\n \n GIT_TARNAME=git-$(GIT_VERSION)\n dist: git.spec git-tar-tree\n@@ -724,4 +731,3 @@ check-docs::\n \t\t*) echo \"no link: $$v\";; \\\n \t\tesac ; \\\n \tdone | sort\n-\n-- \n1.3.2\n"},{"id":"20686","messageId":"7vejyixe5g.fsf@assigned-by-dhcp.cox.net","threadId":"4290","inReplyTo":"87hd3e5ixw.fsf@rho.meyering.net","subject":"Re: [PATCH] Don't write directly to a make target ($@).","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-05-25T16:28:11Z","receivedAt":"2006-05-25T16:28:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jim Meyering <jim@meyering.net> writes:\n\n> Otherwise, if make is suspended, or killed with prejudice, or if the\n> system crashes, you could be left with an up-to-date, yet corrupt,\n> generated file.\n\nThanks.  Maybe you would want a \"make clean\" target for them too\nif you do this.  I often use $@+ instead of t$@ so that I can\nsay \"rm -f *+\" there.\n\n> @@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h\n>  \trm -f $@ && ln git$X $@\n>  \n>  common-cmds.h: Documentation/git-*.txt\n> -\t./generate-cmdlist.sh > $@\n> +\t./generate-cmdlist.sh > t$@\n> +\tmv t$@ $@\n>  \n\nIOW, like this:\n\ncommon-cmds.h: Documentation/git-*.txt\n\trm -f $@+ $@\n        ./generate-cmdlist.sh > $@+\n        mv $@+ $@\n\nclean::\n\trm -f *+\n"},{"id":"20687","messageId":"20060525194125.9380842a.tihirvon@gmail.com","threadId":"4290","inReplyTo":"7vejyixe5g.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Don't write directly to a make target ($@).","fromName":"Timo Hirvonen","fromEmail":"tihirvon@gmail.com","sentAt":"2006-05-25T16:41:25Z","receivedAt":"2006-05-25T16:41:25Z","isPatch":true,"sender":{"key":"tihirvon@gmail.com","avatar":null},"body":"Junio C Hamano <junkio@cox.net> wrote:\n\n> Jim Meyering <jim@meyering.net> writes:\n> \n> > Otherwise, if make is suspended, or killed with prejudice, or if the\n> > system crashes, you could be left with an up-to-date, yet corrupt,\n> > generated file.\n> \n> Thanks.  Maybe you would want a \"make clean\" target for them too\n> if you do this.  I often use $@+ instead of t$@ so that I can\n> say \"rm -f *+\" there.\n> \n> > @@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h\n> >  \trm -f $@ && ln git$X $@\n> >  \n> >  common-cmds.h: Documentation/git-*.txt\n> > -\t./generate-cmdlist.sh > $@\n> > +\t./generate-cmdlist.sh > t$@\n> > +\tmv t$@ $@\n> >  \n> \n> IOW, like this:\n> \n> common-cmds.h: Documentation/git-*.txt\n> \trm -f $@+ $@\n>         ./generate-cmdlist.sh > $@+\n>         mv $@+ $@\n> \n> clean::\n> \trm -f *+\n\nOr just use one tmp file, i.e. \".tmp\" instead of t$@.\n\n-- \nhttp://onion.dynserv.net/~timo/\n"},{"id":"20688","messageId":"874pze5a5f.fsf@rho.meyering.net","threadId":"4290","inReplyTo":"20060525194125.9380842a.tihirvon@gmail.com","subject":"Re: [PATCH] Don't write directly to a make target ($@).","fromName":"Jim Meyering","fromEmail":"jim@meyering.net","sentAt":"2006-05-25T16:42:04Z","receivedAt":"2006-05-25T16:42:04Z","isPatch":true,"sender":{"key":"jim@meyering.net","avatar":"https://avatars.githubusercontent.com/u/710630?v=4"},"body":"Timo Hirvonen <tihirvon@gmail.com> wrote:\n> Or just use one tmp file, i.e. \".tmp\" instead of t$@.\n\nArgh, no.\nThat'd fail big time with parallel builds.\n"},{"id":"20689","messageId":"871wui5a4r.fsf@rho.meyering.net","threadId":"4290","inReplyTo":"7vejyixe5g.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Don't write directly to a make target ($@).","fromName":"Jim Meyering","fromEmail":"jim@meyering.net","sentAt":"2006-05-25T16:42:28Z","receivedAt":"2006-05-25T16:42:28Z","isPatch":true,"sender":{"key":"jim@meyering.net","avatar":"https://avatars.githubusercontent.com/u/710630?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Jim Meyering <jim@meyering.net> writes:\n>\n>> Otherwise, if make is suspended, or killed with prejudice, or if the\n>> system crashes, you could be left with an up-to-date, yet corrupt,\n>> generated file.\n>\n> Thanks.  Maybe you would want a \"make clean\" target for them too\n> if you do this.  I often use $@+ instead of t$@ so that I can\n> say \"rm -f *+\" there.\n\nI chose a prefix rather than a suffix, so that if git is built on a file\nsystem with unreasonable file name length limitations, the prefix will\ndistinguish the temporary from the target; in that situation, a suffixed\ntemporary name could map to the target name.\n\nHowever, assuming reasonable file name length limits, using a suffix is\ngenerally better, since it works even when the target is an absolute\nname.  Adding a prefix obviously won't work with an absolute name.\n\nI'm happy to ignore 14-byte(and 8.3)-limited file systems and\ngo with a suffix, if you still prefer that.  New patch coming up.\n"},{"id":"20691","messageId":"87veru3v4e.fsf@rho.meyering.net","threadId":"4290","inReplyTo":"7vejyixe5g.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Don't write directly to a make target ($@).","fromName":"Jim Meyering","fromEmail":"jim@meyering.net","sentAt":"2006-05-25T16:52:01Z","receivedAt":"2006-05-25T16:52:01Z","isPatch":true,"sender":{"key":"jim@meyering.net","avatar":"https://avatars.githubusercontent.com/u/710630?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Jim Meyering <jim@meyering.net> writes:\n>\n>> Otherwise, if make is suspended, or killed with prejudice, or if the\n>> system crashes, you could be left with an up-to-date, yet corrupt,\n>> generated file.\n>\n> Thanks.  Maybe you would want a \"make clean\" target for them too\n> if you do this.  I often use $@+ instead of t$@ so that I can\n> say \"rm -f *+\" there.\n>\n>> @@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h\n>>  \trm -f $@ && ln git$X $@\n>>\n>>  common-cmds.h: Documentation/git-*.txt\n>> -\t./generate-cmdlist.sh > $@\n>> +\t./generate-cmdlist.sh > t$@\n>> +\tmv t$@ $@\n>>\n>\n> IOW, like this:\n>\n> common-cmds.h: Documentation/git-*.txt\n> \trm -f $@+ $@\n>         ./generate-cmdlist.sh > $@+\n>         mv $@+ $@\n>\n> clean::\n> \trm -f *+\n\nI've included a revised patch below.\n\nI left off the `clean' addition, because I believe \"make clean\" should\nnot remove wildcard patterns like \"*+\", on the off-chance that someone\nuses names like that for files they care about.  Besides, in practice,\nthose temporary files are left behind so rarely that they're not a bother,\nand they're removed again as part of the next build.\n\n\n---------\n\nSubject: [PATCH] Don't write directly to a make target ($@).  Update atomically.\n\nOtherwise, if make is killed with prejudice, or if the system crashes,\nyou could be left with an up-to-date, yet corrupt generated file.\n\n---\n\n Makefile |   34 ++++++++++++++++++++--------------\n 1 files changed, 20 insertions(+), 14 deletions(-)\n\n620173525c5075f2056af107a85881d0d50d3a89\ndiff --git a/Makefile b/Makefile\nindex dbf19c6..04536f6 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h\n \trm -f $@ && ln git$X $@\n \n common-cmds.h: Documentation/git-*.txt\n-\t./generate-cmdlist.sh > $@\n+\t./generate-cmdlist.sh > $@+\n+\tmv $@+ $@\n \n $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh\n-\trm -f $@\n+\trm -f $@ $@+\n \tsed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n \t    -e 's/@@NO_CURL@@/$(NO_CURL)/g' \\\n \t    -e 's/@@NO_PYTHON@@/$(NO_PYTHON)/g' \\\n-\t    $@.sh >$@\n-\tchmod +x $@\n+\t    $@.sh >$@+\n+\tchmod +x $@+\n+\tmv $@+ $@\n \n $(patsubst %.perl,%,$(SCRIPT_PERL)) : % : %.perl\n-\trm -f $@\n+\trm -f $@ $@+\n \tsed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n-\t    $@.perl >$@\n-\tchmod +x $@\n+\t    $@.perl >$@+\n+\tchmod +x $@+\n+\tmv $@+ $@\n \n $(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py\n-\trm -f $@\n+\trm -f $@ $@+\n \tsed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \\\n \t    -e 's|@@GIT_PYTHON_PATH@@|$(GIT_PYTHON_DIR_SQ)|g' \\\n \t    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \\\n-\t    $@.py >$@\n-\tchmod +x $@\n+\t    $@.py >$@+\n+\tchmod +x $@+\n+\tmv $@+ $@\n \n git-cherry-pick: git-revert\n-\tcp $< $@\n+\tcp $< $@+\n+\tmv $@+ $@\n \n git-status: git-commit\n-\tcp $< $@\n+\tcp $< $@+\n+\tmv $@+ $@\n \n # These can record GIT_VERSION\n git$X git.spec \\\n@@ -653,7 +659,8 @@ install-doc:\n ### Maintainer's dist rules\n \n git.spec: git.spec.in\n-\tsed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@\n+\tsed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+\n+\tmv $@+ $@\n \n GIT_TARNAME=git-$(GIT_VERSION)\n dist: git.spec git-tar-tree\n@@ -724,4 +731,3 @@ check-docs::\n \t\t*) echo \"no link: $$v\";; \\\n \t\tesac ; \\\n \tdone | sort\n-\n-- \n1.3.2\n"}]}