Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I have a similar problem and I figured out it.</p> <p>I want to detect forced update within hook script in remote (bare) repository, So my answer might not be suitable for original question, but I hope to be useful my answer for future visitors.</p> <hr> <h1>How to detect forced update or not from in Git hooks script</h1> <p><a href="https://github.com/kyanny/git-hooks-detect-force-update" rel="nofollow noreferrer">https://github.com/kyanny/git-hooks-detect-force-update</a></p> <p>This is a sample git pre-receive hook script for learning about how to detect forced update.</p> <h2>Conclusion</h2> <pre><code>$ git rev-list oldrev ^newrev </code></pre> <h2>How to test</h2> <pre><code>$ rake -T rake forced_push # git hooks test detect forced update rake normal_push # git hooks test </code></pre> <h2>Step-by-Step introduction</h2> <p>Firstly, I describe a syntax of <a href="http://git-scm.com/docs/git-rev-list" rel="nofollow noreferrer">git-rev-list(1)</a>.</p> <p>In this case, we assume within a Git working repository that has this straight history.</p> <pre><code>1 --- 2 --- O --- X --- 3 --- 4 --- N </code></pre> <p>General usage of <code>git-rev-list</code> is below.</p> <pre><code>$ git rev-list N </code></pre> <p>This command will show all of commits reachable from commit N (note: <code>git-rev-list</code> shows commits <em>reverse chronological order</em>)</p> <p><code>git-rev-list</code> accepts multiple arguments.</p> <pre><code>$ git rev-list N O </code></pre> <p>This command will show same output as <code>git rev-list N</code>, because commit O is an ancestor of commit N.</p> <p>Then, <code>git-rev-list</code> allows you to exclude commits from output.</p> <pre><code>$ git rev-list N ^O </code></pre> <p>^O means that to exclude commits reachable from O, so this command will show N, 4, 3, X (note: O is excluded)</p> <hr> <p>Since we are learned about <code>git-rev-list</code>, I describe a case about forced update occured.</p> <p>In this case, we assume within a Git working repository that has this complex history.</p> <pre><code>* --- B --- * --- O ($oldrev) \ * --- X --- * --- N ($newrev) </code></pre> <ol> <li>In old tree, we had 4 commits (*, B, *, O) and pushed them to remote.</li> <li>We checkout a new branch from commit B, it's new tree.</li> <li>In new tree, we had 4 commits (*, X, *, N) and pushed them to remote with --force option!</li> </ol> <p>When pushed, hook pre-receive script invoked with standard input. The format of stdin parameter is described at <a href="http://git-scm.com/docs/githooks" rel="nofollow noreferrer">githooks(5)</a>.</p> <p>Typically, we extract two commit object sha1 from stdin - oldrev and newrev. oldrev is <em>HEAD of old tree</em>, newrev is <em>HEAD of new tree</em>.</p> <p>In this situation, we can detect forced push by <code>git-rev-list</code> output.</p> <p><code>git rev-list oldrev ^newrev</code> shows the commits reachable from oldrev but not reachable from newrev. This shows the commits <em>existed only old tree</em>. If this command show any commits, old tree was replaced with new tree, so forced update was occured. This is what we want!</p> <p>If this command show none of commits, new tree was normally updated, so forced update was not occured. Simply.</p> <h2>See Also</h2> <ul> <li><a href="http://git-scm.com/docs/git-rev-list" rel="nofollow noreferrer">git-rev-list(1)</a></li> <li><a href="http://git.gnus.org/gnus.git/hooks/post-receive-email" rel="nofollow noreferrer">Git hook example: post-receive-email</a></li> <li><a href="https://stackoverflow.com/questions/10319110/how-to-detect-a-forced-update">git - How to detect a forced update - Stack Overflow</a></li> <li><a href="https://stackoverflow.com/questions/9210957/git-hook-to-detect-push-mirror">githooks - Git hook to detect push --mirror - Stack Overflow</a></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload