git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH/RFC 10/20] rebase: factor out command line option processing

From
Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>
Date
Nov 25, 2010, 19:57 UTC
Message-ID
<1290715083-16919-11-git-send-email-martin.von.zweigbergk@gmail.com>
In-Reply-To
<1290715083-16919-1-git-send-email-martin.von.zweigbergk@gmail.com>

Factor out the command line processing in git-rebase--interactive.sh to git-rebase.sh. Store the options in variables in git-rebase.sh and export them before calling git-rebase--interactive.sh.

Signed-off-by: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>
---
 git-rebase--interactive.sh |  223 ++++++++++++-------------------------------
 git-rebase.sh              |   45 +++++----
 2 files changed, 88 insertions(+), 180 deletions(-)
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 886f80b..6389a9f 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -10,29 +10,6 @@
 # The original idea comes from Eric W. Biederman, in
 # http://article.gmane.org/gmane.comp.version-control.git/22407
 
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git-rebase [-i] [options] [--] <upstream> [<branch>]
-git-rebase [-i] (--continue | --abort | --skip)
---
- Available options are
-v,verbose          display a diffstat of what changed upstream
-onto=              rebase onto given branch instead of upstream
-p,preserve-merges  try to recreate merges instead of ignoring them
-s,strategy=        use the given merge strategy
-no-ff              cherry-pick all commits, even if unchanged
-m,merge            always used (no-op)
-i,interactive      always used (no-op)
- Actions:
-continue           continue rebasing process
-abort              abort rebasing process and restore original branch
-skip               skip current patch and continue rebasing process
-no-verify          override pre-rebase hook from stopping the operation
-verify             allow pre-rebase hook to run
-root               rebase all reachable commmits up to the root(s)
-autosquash         move commits that begin with squash!/fixup! under -i
-"
-
 . git-sh-setup
 require_work_tree
 
@@ -105,16 +82,6 @@ AMEND="$DOTEST"/amend
 REWRITTEN_LIST="$DOTEST"/rewritten-list
 REWRITTEN_PENDING="$DOTEST"/rewritten-pending
 
-preserve_merges=
-strategy=
-onto=
-verbose=
-OK_TO_SKIP_PRE_REBASE=
-rebase_root=
-autosquash=
-test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
-force_rebase=
-
 GIT_CHERRY_PICK_HELP="\
 hint: after resolving the conflicts, mark the corrected paths
 hint: with 'git add <paths>' and run 'git rebase --continue'"
@@ -647,15 +614,6 @@ skip_unnecessary_picks () {
 	die "Could not skip unnecessary pick commands"
 }
 
-# check if no other options are set
-is_standalone () {
-	test $# -eq 2 -a "$2" = '--' &&
-	test -z "$onto" &&
-	test -z "$preserve_merges" &&
-	test -z "$strategy" &&
-	test -z "$verbose"
-}
-
 get_saved_options () {
 	test -d "$REWRITTEN" && preserve_merges=t
 	test -f "$DOTEST"/strategy && strategy="$(cat "$DOTEST"/strategy)"
@@ -743,134 +701,77 @@ parse_onto () {
 	git rev-parse --verify "$1^0"
 }
 
-while test $# != 0
-do
-	case "$1" in
-	--no-verify)
-		OK_TO_SKIP_PRE_REBASE=yes
-		;;
-	--verify)
-		OK_TO_SKIP_PRE_REBASE=
-		;;
-	--continue)
-		is_standalone "$@" || usage
-		get_saved_options
-		comment_for_reflog continue
-
-		test -d "$DOTEST" || die "No interactive rebase running"
-
-		# Sanity check
-		git rev-parse --verify HEAD >/dev/null ||
-			die "Cannot read HEAD"
-		git update-index --ignore-submodules --refresh &&
-			git diff-files --quiet --ignore-submodules ||
-			die "Working tree is dirty"
-
-		# do we have anything to commit?
-		if git diff-index --cached --quiet --ignore-submodules HEAD --
+case "$action" in
+continue)
+	get_saved_options
+	comment_for_reflog continue
+
+	test -d "$DOTEST" || die "No interactive rebase running"
+
+	# Sanity check
+	git rev-parse --verify HEAD >/dev/null ||
+		die "Cannot read HEAD"
+	git update-index --ignore-submodules --refresh &&
+		git diff-files --quiet --ignore-submodules ||
+		die "Working tree is dirty"
+
+	# do we have anything to commit?
+	if git diff-index --cached --quiet --ignore-submodules HEAD --
+	then
+		: Nothing to commit -- skip this
+	else
+		. "$AUTHOR_SCRIPT" ||
+			die "Cannot find the author identity"
+		amend=
+		if test -f "$AMEND"
 		then
-			: Nothing to commit -- skip this
-		else
-			. "$AUTHOR_SCRIPT" ||
-				die "Cannot find the author identity"
-			amend=
-			if test -f "$AMEND"
-			then
-				amend=$(git rev-parse --verify HEAD)
-				test "$amend" = $(cat "$AMEND") ||
-				die "\
+			amend=$(git rev-parse --verify HEAD)
+			test "$amend" = $(cat "$AMEND") ||
+			die "\
 You have uncommitted changes in your working tree. Please, commit them
 first and then run 'git rebase --continue' again."
-				git reset --soft HEAD^ ||
-				die "Cannot rewind the HEAD"
-			fi
-			do_with_author git commit --no-verify -F "$MSG" -e || {
-				test -n "$amend" && git reset --soft $amend
-				die "Could not commit staged changes."
-			}
+			git reset --soft HEAD^ ||
+			die "Cannot rewind the HEAD"
 		fi
+		do_with_author git commit --no-verify -F "$MSG" -e || {
+			test -n "$amend" && git reset --soft $amend
+			die "Could not commit staged changes."
+		}
+	fi
 
-		record_in_rewritten "$(cat "$DOTEST"/stopped-sha)"
+	record_in_rewritten "$(cat "$DOTEST"/stopped-sha)"
 
-		require_clean_work_tree "rebase"
-		do_rest
-		;;
-	--abort)
-		is_standalone "$@" || usage
-		get_saved_options
-		comment_for_reflog abort
-
-		git rerere clear
-		test -d "$DOTEST" || die "No interactive rebase running"
-
-		HEADNAME=$(cat "$DOTEST"/head-name)
-		HEAD=$(cat "$DOTEST"/head)
-		case $HEADNAME in
-		refs/*)
-			git symbolic-ref HEAD $HEADNAME
-			;;
-		esac &&
-		output git reset --hard $HEAD &&
-		rm -rf "$DOTEST"
-		exit
-		;;
-	--skip)
-		is_standalone "$@" || usage
-		get_saved_options
-		comment_for_reflog skip
+	require_clean_work_tree "rebase"
+	do_rest
+	;;
+abort)
+	get_saved_options
+	comment_for_reflog abort
 
-		git rerere clear
-		test -d "$DOTEST" || die "No interactive rebase running"
+	git rerere clear
+	test -d "$DOTEST" || die "No interactive rebase running"
 
-		output git reset --hard && do_rest
-		;;
-	-s)
-		case "$#,$1" in
-		*,*=*)
-			strategy=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
-		1,*)
-			usage ;;
-		*)
-			strategy="$2"
-			shift ;;
-		esac
-		;;
-	-m)
-		# we use merge anyway
-		;;
-	-v)
-		verbose=t
-		;;
-	-p)
-		preserve_merges=t
-		;;
-	-i)
-		# yeah, we know
-		;;
-	--no-ff)
-		force_rebase=t
-		;;
-	--root)
-		rebase_root=t
-		;;
-	--autosquash)
-		autosquash=t
-		;;
-	--no-autosquash)
-		autosquash=
-		;;
-	--onto)
-		test 2 -le "$#" || usage
-		onto="$2"
-		shift
-		;;
-	--)
-		shift
-		break
+	HEADNAME=$(cat "$DOTEST"/head-name)
+	HEAD=$(cat "$DOTEST"/head)
+	case $HEADNAME in
+	refs/*)
+		git symbolic-ref HEAD $HEADNAME
 		;;
-	esac
-	shift
-done
+	esac &&
+	output git reset --hard $HEAD &&
+	rm -rf "$DOTEST"
+	exit
+	;;
+skip)
+	get_saved_options
+	comment_for_reflog skip
+
+	git rerere clear
+	test -d "$DOTEST" || die "No interactive rebase running"
+
+	output git reset --hard && do_rest
+	;;
+esac
 
 if test -n "$onto"
 then
diff --git a/git-rebase.sh b/git-rebase.sh
index ed1d4f5..df4e184 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -56,6 +56,9 @@ rebase_root=
 force_rebase=
 allow_rerere_autoupdate=
 action=
+preserve_merges=
+autosquash=
+test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 
 read_state () {
 	if test -d "$merge_dir"
@@ -171,27 +174,14 @@ finish_rb_merge () {
 	say All done.
 }
 
-is_interactive () {
-	while test $# != 0
-	do
-		case "$1" in
-			-i|--interactive)
-				interactive_rebase=explicit
-				break
-			;;
-			-p|--preserve-merges)
-				interactive_rebase=implied
-			;;
-		esac
-		shift
-	done
-
+run_interactive_rebase () {
 	if [ "$interactive_rebase" = implied ]; then
 		GIT_EDITOR=:
 		export GIT_EDITOR
 	fi
-
-	test -n "$interactive_rebase" || test -f "$merge_dir"/interactive
+	export onto autosquash strategy strategy_opts verbose rebase_root \
+	force_rebase action preserve_merges OK_TO_SKIP_PRE_REBASE
+	exec git-rebase--interactive "$@"
 }
 
 run_pre_rebase_hook () {
@@ -206,8 +196,6 @@ run_pre_rebase_hook () {
 test -f "$apply_dir"/applying &&
 	die 'It looks like git-am is in progress. Cannot rebase.'
 
-is_interactive "$@" && exec git-rebase--interactive "$@"
-
 while test $# != 0
 do
 	case "$1" in
@@ -227,6 +215,19 @@ do
 		onto="$2"
 		shift
 		;;
+	-i|--interactive)
+		interactive_rebase=explicit
+		;;
+	-p|--preserve-merges)
+		preserve_merges=t
+		test -z "$interactive_rebase" && interactive_rebase=implied
+		;;
+	--autosquash)
+		autosquash=t
+		;;
+	--no-autosquash)
+		autosquash=
+		;;
 	-M|-m|--m|--me|--mer|--merg|--merge)
 		do_merge=t
 		;;
@@ -351,6 +352,10 @@ valuable there.'
 	test $# -eq 0 && test -z "$rebase_root" && usage
 fi
 
+test -f "$merge_dir"/interactive && interactive_rebase=explicit
+
+test -n "$action" && test -n "$interactive_rebase" && run_interactive_rebase
+
 case "$action" in
 continue)
 	git update-index --ignore-submodules --refresh &&
@@ -409,6 +414,8 @@ abort)
 	;;
 esac
 
+test -n "$interactive_rebase" && run_interactive_rebase "$@"
+
 require_clean_work_tree "rebase" "Please commit or stash them."
 
 if test -z "$rebase_root"
-- 
1.7.3.2.864.gbbb96
Previous: Martin von ZweigbergkNext: Martin von Zweigbergk
Message 15 of 29 in “Refactor rebase”
  1. 00/20 Refactor rebaseMartin von Zweigbergk, Nov 25, 2010
  2. 01/20 rebase: clearer names for directory variablesMartin von Zweigbergk, Nov 25, 2010
  3. 02/20 rebase: refactor reading of stateMartin von Zweigbergk, Nov 25, 2010
  4. 03/20 rebase: read state outside loopMartin von Zweigbergk, Nov 25, 2010
  5. 04/20 rebase: remove unused rebase state 'prev_head'Martin von Zweigbergk, Nov 25, 2010
  6. Michael J GruberNov 26, 2010
  7. Martin von ZweigbergkNov 26, 2010
  8. Junio C HamanoNov 29, 2010
  9. Michael J GruberNov 30, 2010
  10. 05/20 rebase: act on command line outside parsing loopMartin von Zweigbergk, Nov 25, 2010
  11. 06/20 rebase: collect check for existing rebaseMartin von Zweigbergk, Nov 25, 2010
  12. 07/20 rebase: stricter check on argumentsMartin von Zweigbergk, Nov 25, 2010
  13. 08/20 rebase: align variable namesMartin von Zweigbergk, Nov 25, 2010
  14. 09/20 rebase: align variable contentMartin von Zweigbergk, Nov 25, 2010
  15. 10/20 rebase: factor out command line option processingMartin von Zweigbergk, Nov 25, 2010
  16. 11/20 rebase -i: remove now unnecessary directory checksMartin von Zweigbergk, Nov 25, 2010
  17. 12/20 rebase: reorder validation stepsMartin von Zweigbergk, Nov 25, 2010
  18. 13/20 rebase: factor out reference parsingMartin von Zweigbergk, Nov 25, 2010
  19. 14/20 rebase: factor out clean work tree checkMartin von Zweigbergk, Nov 25, 2010
  20. 15/20 rebase: factor out call to pre-rebase hookMartin von Zweigbergk, Nov 25, 2010
  21. 16/20 rebase -i: support --statMartin von Zweigbergk, Nov 25, 2010
  22. 17/20 rebase: improve detection of rebase in progressMartin von Zweigbergk, Nov 25, 2010
  23. 18/20 rebase -m: extract code to new source fileMartin von Zweigbergk, Nov 25, 2010
  24. 19/20 rebase: extract am code to new source fileMartin von Zweigbergk, Nov 25, 2010
  25. 20/20 rebase: show consistent conflict resolution hintMartin von Zweigbergk, Nov 25, 2010
  26. Martin von ZweigbergkNov 25, 2010
  27. Sverre RabbelierNov 26, 2010
  28. Martin von ZweigbergkNov 26, 2010
  29. Sverre RabbelierNov 27, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.