Johan Herland <johan@xxxxxxxxxxx> writes: > Overnight, it occured to me that --force-if-expected could be > simplified by leveraging the existing --force option; for the above > two examples, respectively: > > $ git push --force --expect > # validate foo @ origin == @{upstream} before pushing > > and > > $ git push --force --expect=refs/original/foo my_remote HEAD:foo > # validate foo @ my_remote == refs/original/foo before pushing First, on the name. I do not think either "--validate" or "--expect" is particularly a good one. The former lets this feature squat on a good name that covers a much broader spectrum, forbidding people from adding other kinds of validation later. "--expect" is slightly less bad in that sense; saying "we expect this" does imply "otherwise it is an unexpected situation and we would fail", but the name still does not feel ideal. What is the essense of compare-and-swap? Perhaps we can find a good word by thinking that question through. To me, it is a way to implement a "lock" on the remote ref without actually taking a lock (which would leave us open for a stale lock), and this "lock"-ness is what we want in order to guarantee safety. So we could perhaps call it "--lockref"? I'll leave the name open but tentatively use this name in the following, primarily to see how well it sits on the command line examples. Then on the semantics/substance. I had quite a similar thought as you had while reading your initial response. In the most generic form, we would want to be able to pass necessary information fully via the option, i.e. --lockref=theirRefName:expectedValue but when the option is spelled without details, we could fill in the default values by making a reasonable guess of what the user could have meant. If we only have --lockref without refname nor value, then we will enable the safety for _all_ refs that we are going to update during this push. If we have --lockref=theirRefName without the expected value for that ref, we will enable the safety only for the ref (you can give more than one --lockref=theirRefName), and guess what value we should expect. If we have a fully specified option, we do not have to guess the value. And for the expected value, when we have a tracking branch for the branch at the remote we are trying to update, its value is a very good guess of what the user meant. Note, however, that this is very different from @{upstream}. You could be pushing a branch "frotz", that is configured to integrate with "master" taken from "origin", but (1) to a branch different from "master" of "origin", e.g. $ git push --lockref origin frotz:nitfol $ git push --lockref origin :nitfol ;# deleting (2) even to a branch of a remote that is different from "origin", e.g. $ git push --lockref xyzzy frotz:nitfol $ git push --lockref xyzzy :nitfol ;# deleting Even in these case, if you have a remote tracking branch for the destination (i.e. you have refs/remotes/origin/nitfol in case (1) or refs/remotes/xyzzy/nitfol in case (2) to be updated by fetching from origin or xyzzy), we can and should use that value as the default. There is no room for frotz@{upstream} (or @{upstream} of the current branch) to get in the picture. Except when you happen to be pushing with "push.default = upstream", that is. But that is a natural consequence of the more generic check with "our remote tracking branch of the branch we are updating at the remote" rule. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html