From: Martin Waitz <tali@admingilde.org>
To: git@vger.kernel.org
Subject: [RFC] git commit --branch
Date: Mon, 29 May 2006 22:28:55 +0200 [thread overview]
Message-ID: <20060529202851.GE14325@admingilde.org> (raw)
Allow to commit to another branch and creating a merge in the current branch.
Sometimes it is neccessary to have some local modifications in the tree
in order to test it and work with it. With this patch you can have
one working tree which combines several topic branches in order to
develop and test your changes. When your changes are ready, you can
commit them to the appropriate topic branch.
With the --branch option, the commit will automatically be rebased to
that branch. The original tree will then be commited to your working
branch as a merge.
---
Perhaps something like this can even be integrated into the extended
branch configuration which is currently under discussion.
It may make sense to have one branch which always contains a merge
of a selected set of other branches and having a default branch
for new commits.
Documentation/git-commit.txt | 6 +++
git-commit.sh | 62 ++++++++++++++++++++++++++++++++++-
t/t3800-commit-onto-other-branch.sh | 32 ++++++++++++++++++
3 files changed, 99 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 38df59c..8111ba4 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -49,6 +49,12 @@ OPTIONS
Override the author name used in the commit. Use
`A U Thor <author@example.com>` format.
+--branch <branch>::
+ Actually commit the changes to another branch.
+ Afterwards it will be merged into the current branch.
+ This is useful if you work on a branch with local modifications
+ but want to keep one clean branch without those.
+
-m <msg>::
Use the given <msg> as the commit message.
diff --git a/git-commit.sh b/git-commit.sh
index 1983d45..9ed0050 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -3,7 +3,7 @@ #
# Copyright (c) 2005 Linus Torvalds
# Copyright (c) 2006 Junio C Hamano
-USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-u] [--amend] [-e] [--author <author>] [[-i | -o] <path>...]'
+USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-u] [--amend] [-e] [--author <author>] [--branch <branch>] [[-i | -o] <path>...]'
SUBDIRECTORY_OK=Yes
. git-sh-setup
@@ -245,6 +245,12 @@ do
force_author="$1"
shift
;;
+ -b|--b|--br|--bra|--bran|--branc|--branch)
+ case "$#" in 1) usage ;; esac
+ shift
+ onto_branch="$1"
+ shift
+ ;;
-e|--e|--ed|--edi|--edit)
no_edit=
shift
@@ -405,6 +411,7 @@ t,,[1-9]*)
die "No paths with -i does not make sense." ;;
esac
+
################################################################
# Prepare index to have a tree to be committed
@@ -623,6 +630,32 @@ else
current=
fi
+if test -n "$onto_branch"
+then
+ onto_branch_commit=$(git-rev-parse --verify "$onto_branch") ||
+ die "Branch $onto_branch does not exist."
+ test $(git merge-base "$onto_branch" HEAD) = $onto_branch_commit ||
+ die "Branch "$onto_branch" already contains unmerged commits."
+ case "$PARENTS" in
+ -p*-p*) die "Cannot commit a merge to another branch." ;;
+ esac
+ if test $(git-rev-parse --verify HEAD) = $onto_branch_commit
+ then
+ # no merge neccessary, branches identically
+ forward_onto_branch="$onto_branch"
+ onto_branch=""
+ fi
+ if test "$amend" = t
+ then
+ # test that the tip of HEAD really came from the tip of
+ # $onto_branch and that we can amend both of them
+ test $(git merge-base "$onto_branch" HEAD^) != $onto_branch_commit &&
+ test $(git merge-base "$onto_branch"^ HEAD^) = $(git rev-parse --verify "$onto_branch"^) ||
+ die "commits on $onto_branch and HEAD differ, cannot amend."
+ onto_branch_commit=$(git rev-parse --verify "$onto_branch"^)
+ fi
+fi
+
if test -z "$no_edit"
then
{
@@ -689,8 +722,35 @@ then
tree=$(GIT_INDEX_FILE="$TMP_INDEX" git-write-tree) &&
rm -f "$TMP_INDEX"
fi &&
+ if test -n "$onto_branch"
+ then
+ # create temporary index
+ ONTO_INDEX="$GIT_DIR/onto-index"
+ cp "$USE_INDEX" "$ONTO_INDEX" &&
+ GIT_INDEX_FILE="$ONTO_INDEX" \
+ git-read-tree -i -m "$onto_branch_commit"
+ # merge new changes into the branch
+ GIT_INDEX_FILE="$ONTO_INDEX" \
+ git-read-tree -i --aggressive -m \
+ HEAD "$onto_branch_commit" "$tree" &&
+ GIT_INDEX_FILE="$ONTO_INDEX" \
+ git-merge-index git-merge-one-file -a || {
+ echo >&2 "Cannot rebase your commit to $onto_branch."
+ echo >&2 "Please merge and commit manually."
+ false
+ } &&
+ tree2=$(GIT_INDEX_FILE="$ONTO_INDEX" git-write-tree) &&
+ commit2=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree2 -p $onto_branch_commit) &&
+ git update-ref "$onto_branch" $commit2 &&
+ rm -f "$ONTO_INDEX" &&
+ PARENTS="$PARENTS -p $commit2"
+ fi &&
commit=$(cat "$GIT_DIR"/COMMIT_MSG | git-commit-tree $tree $PARENTS) &&
git-update-ref HEAD $commit $current &&
+ if test -n "$forward_onto_branch"
+ then
+ git-update-ref "$forward_onto_branch" $commit $current
+ fi &&
rm -f -- "$GIT_DIR/MERGE_HEAD" &&
if test -f "$NEXT_INDEX"
then
diff --git a/t/t3800-commit-onto-other-branch.sh b/t/t3800-commit-onto-other-branch.sh
new file mode 100755
index 0000000..f4f6410
--- /dev/null
+++ b/t/t3800-commit-onto-other-branch.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Martin Waitz
+#
+
+test_description='Test a commit to another branch'
+
+. ./test-lib.sh
+
+echo AAA > A
+echo BBB > B
+
+test_expect_success 'Initial commit' \
+'git add A B &&
+ git commit -m "Initial commit" &&
+ git branch topic'
+
+test_expect_success 'Modify HEAD' \
+'echo A2 > A &&
+ git commit -m "modify A" A'
+
+test_expect_success 'Commit to branch' \
+'echo B2 > B &&
+ git commit -m "modify B" --branch topic B'
+
+# now test that HEAD and topic only differs in A
+test_expect_success 'Verify trees' \
+'echo ":100644 100644 43d5a8e... 3ce238a... M A" > expected &&
+ git diff-tree --abbrev topic HEAD > current &&
+ diff expected current'
+
+test_done
--
1.3.3.ged90
--
Martin Waitz
next reply other threads:[~2006-05-29 20:29 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-29 20:28 Martin Waitz [this message]
2006-05-29 20:41 ` [RFC] git commit --branch Shawn Pearce
2006-05-29 21:22 ` Martin Waitz
2006-05-29 21:35 ` Shawn Pearce
2006-05-29 21:55 ` Martin Waitz
2006-05-29 22:16 ` Shawn Pearce
2006-05-29 21:14 ` Johannes Schindelin
2006-05-29 21:27 ` Jakub Narebski
2006-05-29 21:37 ` Martin Waitz
2006-05-29 21:58 ` Johannes Schindelin
2006-05-30 9:12 ` Junio C Hamano
2006-05-30 21:05 ` Martin Waitz
2006-05-30 22:52 ` Junio C Hamano
2006-05-31 15:21 ` Martin Waitz
2006-06-05 18:22 ` Jon Loeliger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060529202851.GE14325@admingilde.org \
--to=tali@admingilde.org \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).