Junio C Hamano <junkio@xxxxxxx> writes: > I think you can do something along the following line. > > (1) You say "for-each-ref --all" to get the ref information > that is after update. > > (2) Instead of looping and processing one at a time, grab all > information upfront. replace the object name you obtained > in (1) for the ref being updated with the oldrev info you > discovered. > > (3) Handle the branch one at a time, but instead of using --all, > use the result of (2) as the "state of the repository and > its refs before this update". > > In other words, you have enough information to reconstruct the > view of the repository before your push took place. After > running "for-each-ref --all" once upfront, you reconstruct such > a view, and after that you do not ever look at where the real > refs are in the repository. That would perhaps alleviate the > issue of racing pushers as a side effect. A couple of issues around the above suggestion. Incidentally, the above fixes the "pushing tag and then commit, and pushing commit and then tag, would give different results" problem, as "what's new" computation would not consider the commits the updated tag brought in as "old" commits anymore. The above fixes "when pushing two branches that share new commits, the shared commits will not be shown on any reports" problem, but if you literally implement it the way I suggested, you would instead list such shared commits that are new to the repository in reports for both branches. This may or may not be a problem, depending on your definition of "new to the repository". On one hand, they *are* new commits introduced by this push (that updates both branches), so in that sense, showing them on reports for both branches may be the right thing to do. On the other hand, you would not see these shared commits on the report for the latter branch if you did the same push as two separate "git push $URL A; git push $URL B" invocations, so showing them only on the report for one of the branches may be the right thing to do, even when they are pushed together (by the way, this is one of the reasons that I think "new to the repository" is wrong. I do not think its semantics is well-defined). If you want to implement the latter semantics, then after you handle one branch in step (3), you can replace the internal view of "what the repository looked like before this push" by replacing the commit associated with the branch you just have dealt with (which you replaced with its $oldrev in step (2) in the data read from 'for-each-ref --all') with its $newrev. Then the shared commits would be part of the old state of the repository when you handle the other ref, and would not show up in its report. If you do this, you would not want to replace the data after handing a tag, in order to preserve the fix for "new tag hides new commits" problem. - 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