Add the script and reword README
parent
4f367c8e16
commit
524c2ef8a9
|
@ -1,3 +1,3 @@
|
|||
# git-force
|
||||
|
||||
small utility to explain a force push before pushing, to help prevent accidents with git fetch and --force-with-lease
|
||||
A small utility to display what commits will be dropped and which will be added, and attempts to prevent overwrites with `--force-with-lease` from programs that repeadetly `git fetch`, and double checks remote and local to error out if any changed after confirming.
|
|
@ -0,0 +1,131 @@
|
|||
#!/bin/bash
|
||||
if [[ "$1" == "--help" || "$1" == "-h" ]]
|
||||
then
|
||||
echo "Usage:"
|
||||
echo " git force"
|
||||
echo " git force <remote>"
|
||||
echo " git force <remote> <branch>"
|
||||
exit 0
|
||||
fi
|
||||
REMOTE=""
|
||||
BRANCH=""
|
||||
PRETTY="--pretty=format:%h, %an <%ae>, %ar: %s"
|
||||
if [[ "$#" == "0" ]]
|
||||
then
|
||||
BRANCH="$(git branch --show-current)"
|
||||
if [[ "$BRANCH" == "" ]]
|
||||
then
|
||||
echo "error: currently in detached HEAD state" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [[ "$#" -gt "0" ]]
|
||||
then
|
||||
REMOTE="$1"
|
||||
git config "remote.$REMOTE.url" > /dev/null 2>&1
|
||||
if [[ "$?" != "0" ]]
|
||||
then
|
||||
echo "error: specified remote is invalid" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
if [[ "$#" -gt "1" ]]
|
||||
then
|
||||
BRANCH="$2"
|
||||
git rev-parse --verify "$BRANCH" > /dev/null 2>&1
|
||||
if [[ "$?" != "0" ]]
|
||||
then
|
||||
echo "error: specified branch is invalid" >&2
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
if [[ "$REMOTE" == "" ]]
|
||||
then
|
||||
REMOTE=$(git config "branch.$BRANCH.remote")
|
||||
if [[ "$?" != "0" ]]
|
||||
then
|
||||
echo "error: current branch does not have a remote and no remote was specified" >&2
|
||||
echo "see: git force --help"
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
if [[ "$REMOTE" == "" || "$BRANCH" == "" ]]
|
||||
then
|
||||
echo "assertion failed: remote or branch is blank" >&2
|
||||
exit 5
|
||||
fi
|
||||
REMOTE_BRANCH="$REMOTE/$BRANCH"
|
||||
REMOTE_HASH="$(git rev-parse "$REMOTE_BRANCH")" # later used to throw errors if something changes remote or local
|
||||
if [[ "$?" != "0" || "$REMOTE_HASH" == "" ]]
|
||||
then
|
||||
echo "internal error: failed to fetch remote hash" >&2
|
||||
exit 5
|
||||
fi
|
||||
LOCAL_HASH="$(git rev-parse "$BRANCH")" # as that may cause the user unintentionally pushing/overwriting unwanted things
|
||||
if [[ "$?" != "0" || "$LOCAL_HASH" == "" ]]
|
||||
then
|
||||
echo "internal error: failed to fetch local hash" >&2
|
||||
exit 5
|
||||
fi
|
||||
|
||||
if [[ "$REMOTE_HASH" == "$LOCAL_HASH" ]]
|
||||
then
|
||||
echo "error: the branches are already the same" >&2
|
||||
exit 8
|
||||
fi
|
||||
|
||||
if [[ "$REMOTE_HASH" == "$FORK_POINT" ]]
|
||||
then
|
||||
echo "error: the branches have not diverged" >&2
|
||||
exit 9
|
||||
fi
|
||||
|
||||
FORK_POINT="$(git merge-base "$BRANCH" "$REMOTE_BRANCH")"
|
||||
if [[ "$?" != "0" ]]
|
||||
then
|
||||
echo "The branches do not have a common ancestor, the latest commits for each are listed below:"
|
||||
echo ""
|
||||
echo "remote:"
|
||||
git show -s "$PRETTY" "$REMOTE_HASH"
|
||||
echo ""
|
||||
echo "remote:"
|
||||
git show -s "$PRETTY" "$REMOTE_HASH"
|
||||
else
|
||||
echo "The following commits will be OVERWRITTEN:"
|
||||
git log "$PRETTY" "$FORK_POINT..$REMOTE_HASH"
|
||||
echo ""
|
||||
echo "The following commits will overwrite the above commits:"
|
||||
git log "$PRETTY" "$FORK_POINT..$LOCAL_HASH"
|
||||
fi
|
||||
echo ""
|
||||
read -p "Continue? [y/N] " SHOULD_CONTINUE
|
||||
if [[ "$SHOULD_CONTINUE" != "y" ]]
|
||||
then
|
||||
echo "Abort." >&2
|
||||
exit 6
|
||||
fi
|
||||
REMOTE_HASH_2="$(git rev-parse "$REMOTE_BRANCH")"
|
||||
LOCAL_HASH_2="$(git rev-parse "$BRANCH")"
|
||||
if [[ "$REMOTE_HASH_2" != "$REMOTE_HASH" ]]
|
||||
then
|
||||
echo "@@@@@@@@@@@@@@@@@@@@@@@@@" >&2
|
||||
echo "@ REMOTE HAS UPDATED! @" >&2
|
||||
echo "@@@@@@@@@@@@@@@@@@@@@@@@@" >&2
|
||||
echo "" >&2
|
||||
echo "The remote updated from $REMOTE_HASH"
|
||||
echo "to $REMOTE_HASH_2 while you were confirming."
|
||||
echo "Please re-run this command and check again."
|
||||
exit 7
|
||||
fi
|
||||
if [[ "$LOCAL_HASH_2" != "$LOCAL_HASH" ]]
|
||||
then
|
||||
echo "@@@@@@@@@@@@@@@@@@@@@@@@" >&2
|
||||
echo "@ LOCAL HAS UPDATED! @" >&2
|
||||
echo "@@@@@@@@@@@@@@@@@@@@@@@@" >&2
|
||||
echo "" >&2
|
||||
echo "The local updated from $LOCAL_HASH"
|
||||
echo "to $LOCAL_HASH_2 while you were confirming."
|
||||
echo "Please re-run this command and check again."
|
||||
exit 7
|
||||
fi
|
||||
git push --force-with-lease "$REMOTE" "$BRANCH"
|
Loading…
Reference in New Issue