summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-05-25 13:24:22 +0100
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2012-05-25 13:24:22 +0100
commit8414a7f8d0a68a0200e45aa6c4415cf594808c30 (patch)
tree6354653873814ac80753373478b9027a818d1d9d
parent84acc740efea6570b5d371462bc66d0b8b49671a (diff)
downloadgit-pull-request-8414a7f8d0a68a0200e45aa6c4415cf594808c30.tar.bz2
attach
-rwxr-xr-xgit-pull-request.sh144
1 files changed, 134 insertions, 10 deletions
diff --git a/git-pull-request.sh b/git-pull-request.sh
index 7ba565f..ca16004 100755
--- a/git-pull-request.sh
+++ b/git-pull-request.sh
@@ -16,6 +16,8 @@ needs-work Indicate a pull request needs additional work before merging
reject Reject a pull request
archive Archive a pull request
+attach Attach a file to a pull request
+
--
General Options
q,quiet Be less verbose
@@ -26,6 +28,9 @@ H,heads Show the non-archived pull requests
A,archive Show the archived pull requests
w,waiting Show only those which are 'waiting' on review/merge
p,pattern= Specify a regexp to match for which pull requests to show
+
+ Attach Options
+o,overwrite Overwrite any extant file with the new one given
"
. git-sh-setup
@@ -43,6 +48,7 @@ do
-H) SHOW_HEADS=1 ;;
-A) SHOW_ARCHIVE=1 ;;
-w) SHOW_WAITING=1 ;;
+ -o) OVERWRITE_ATTACH=1 ;;
-p) SHOW_PATTERN="$2"; shift ;;
--) shift; break;;
*) usage ;;
@@ -61,6 +67,14 @@ fi
## Utility functions ######################################################
#############################################################################
+PR_META_FILE="${GIT_DIR}/PULL_REQUEST_META"
+PR_EDIT_MSG="${GIT_DIR}/PULL_REQUEST_EDITMSG"
+PR_INDEX_FILE="${GIT_DIR}/PULL-REQUEST.index"
+
+#############################################################################
+## Utility functions ######################################################
+#############################################################################
+
rgit ()
{
test "x$GIT_SHOWCMD" = "x1" && echo >&2 "+ git $*"
@@ -114,6 +128,20 @@ load_meta_from ()
METADATA[ROOT]=$(first_commit_on "${SHA}")
}
+load_index_from ()
+{
+ local SHA
+ SHA="$1"
+ rm -f "${PR_INDEX_FILE}"
+ GIT_INDEX_FILE="${PR_INDEX_FILE}" rgit read-tree "${SHA}"
+}
+
+meta_file_exists ()
+{
+ GIT_INDEX_FILE="${PR_INDEX_FILE}" rgit ls-files --cached | \
+ sane_grep -q '^'"$1"'$'
+}
+
display_meta_summary ()
{
local PR
@@ -135,14 +163,14 @@ summarise_meta_at ()
inject_metadata_file ()
{
- cat > "${GIT_DIR}/PULL_REQUEST_META" <<EOF
+ cat > "${PR_META_FILE}" <<EOF
STATE=${METADATA[STATE]}
COMMIT=${METADATA[COMMIT]}
LANDINTO=${METADATA[LANDINTO]}
ONTOP=${METADATA[ONTOP]}
EOF
- rgit hash-object -t blob -w "${GIT_DIR}/PULL_REQUEST_META"
- rm -f "${GIT_DIR}/PULL_REQUEST_META"
+ rgit hash-object -t blob -w "${PR_META_FILE}"
+ rm -f "${PR_META_FILE}"
}
commit_is_merged ()
@@ -155,6 +183,11 @@ commit_is_merged ()
return 0
}
+sanitise_filename ()
+{
+ echo "$1" | sed -e's@^[\./]*@@' -e's@/[\.]*@/@g'
+}
+
#############################################################################
## Command implementations ################################################
#############################################################################
@@ -260,7 +293,7 @@ cmd_create () {
$(rgit symbolic-ref HEAD))
# 2. Produce precis template and edit it
- cat > "${GIT_DIR}/PULL_REQUEST_EDITMSG" <<EOF
+ cat > "${PR_EDIT_MSG}" <<EOF
# This message will become the precis for your pull request.
# If you do not want to create the pull request, you should quit the editor
@@ -279,13 +312,13 @@ cmd_create () {
#
EOF
local PRESUM POSTSUM
- PRESUM=$(rgit hash-object -t blob "${GIT_DIR}/PULL_REQUEST_EDITMSG")
- git_editor "${GIT_DIR}/PULL_REQUEST_EDITMSG"
- POSTSUM=$(rgit hash-object -t blob "${GIT_DIR}/PULL_REQUEST_EDITMSG")
+ PRESUM=$(rgit hash-object -t blob "${PR_EDIT_MSG}")
+ git_editor "${PR_EDIT_MSG}"
+ POSTSUM=$(rgit hash-object -t blob "${PR_EDIT_MSG}")
# 2.5 (if unchanged, clean up and quit)
if test "x$PRESUM" = "x$POSTSUM"; then
echo >&2 "Message unchanged, aborting creation of pull-request"
- rm -f "${GIT_DIR}/PULL_REQUEST_EDITMSG"
+ rm -f "${PR_EDIT_MSG}"
exit 1
fi
# 3. Create metadata file, tree, commit and ref.
@@ -293,13 +326,13 @@ EOF
METASUM=$(inject_metadata_file)
TREESUM=$(echo -e "100644 blob ${METASUM}\tpull-request.meta" | \
rgit mktree)
- COMMITSUM=$(sed -e'/^#/d' < "${GIT_DIR}/PULL_REQUEST_EDITMSG" | \
+ COMMITSUM=$(sed -e'/^#/d' < "${PR_EDIT_MSG}" | \
rgit commit-tree "${TREESUM}")
rgit update-ref -m "Creation of pull-request ${PR}" \
"refs/pull-requests/heads/${PR}__meta" "${COMMITSUM}"
rgit update-ref -m "Copying anchor for pull-request ${PR}" \
"refs/pull-requests/heads/${PR}__anchor" "${METADATA[COMMIT]}"
- rm -f "${GIT_DIR}/PULL_REQUEST_EDITMSG"
+ rm -f "${PR_EDIT_MSG}"
echo "Pull request ${PR} created successfully"
}
@@ -360,6 +393,97 @@ cmd_merge () {
rgit merge --no-ff --no-commit "${MERGESRC}"
}
+cmd_attach () {
+ local PR FILE AS
+ PR="$1"
+ FILE="$2"
+ AS="$3"
+ if test "x$PR" = "x"; then
+ echo >&2 "Please specify a pull-request name to attach files to."
+ exit 1
+ fi
+ if test "x$FILE" = "x"; then
+ echo >&2 "Please specify a file to attach to the pull-request."
+ exit 1
+ fi
+ if test "x$AS" = "x"; then
+ AS=$(sanitise_filename $(basename "$FILE"))
+ else
+ AS=$(sanitise_filename "$AS")
+ fi
+
+ # Verify that the PR exists, that $FILE exists, and that $AS is not
+ # already present. If $AS is present and --overwrite was not given
+ # then refuse to continue
+ local COMMIT BRANCH
+ while read _COMMIT _BRANCH; do
+ COMMIT="${_COMMIT}"
+ BRANCH="${_BRANCH}"
+ done <<<$(rgit show-ref "$PR"__meta)
+ if test "x$COMMIT" = "x"; then
+ echo >&2 "Specified pull request '${PR}' does not exist."
+ exit 1
+ fi
+ load_meta_from "${COMMIT}"
+
+ if ! test -e "$FILE"; then
+ echo >&2 "Unable to find '${FILE}', sorry"
+ exit 1
+ fi
+
+ load_index_from "${COMMIT}"
+
+ if meta_file_exists "attached/${AS}"; then
+ if test "x$OVERWRITE_ATTACH" = "x"; then
+ echo >&2 "Unable to continue, '${AS}' already attached"
+ exit 1
+ fi
+ fi
+
+ # Concoct a commit message
+ cat > "${PR_EDIT_MSG}" <<EOF
+
+# This message will become the reasoning for attaching this file. If you do
+# not want to attach the file to the pull request, you should quit the editor
+# without saving the file.
+#
+# Any line starting with a hash mark will be removed before the attachment
+# is committed to the repository.
+#
+# The first line of your message will be used as the title and the remainder
+# will be the body of the reasoning. The entire message will be used as the
+# commit message on the pull request.
+#
+# This pull request is called: ${PR}
+# You are attaching: ${FILE}
+# And it's being called: ${AS}
+#
+EOF
+ local PRESUM POSTSUM
+ PRESUM=$(rgit hash-object -t blob "${PR_EDIT_MSG}")
+ git_editor "${PR_EDIT_MSG}"
+ POSTSUM=$(rgit hash-object -t blob "${PR_EDIT_MSG}")
+ # 2.5 (if unchanged, clean up and quit)
+ if test "x$PRESUM" = "x$POSTSUM"; then
+ echo >&2 "Message unchanged, aborting file attachment"
+ rm -f "${PR_EDIT_MSG}"
+ exit 1
+ fi
+
+ local FSHA
+ FSHA=$(rgit hash-object -t blob -w "${FILE}")
+ GIT_INDEX_FILE="${PR_INDEX_FILE}" rgit update-index --add \
+ --cacheinfo "100644" "${FSHA}" "attached/${AS}"
+ local TSHA
+ TSHA=$(GIT_INDEX_FILE="${PR_INDEX_FILE}" rgit write-tree)
+ local CSHA
+ CSHA=$(sed -e'/^#/d' < "${PR_EDIT_MSG}" | \
+ rgit commit-tree "${TSHA}" -p "${METADATA[META_SHA]}")
+ rgit update-ref -m "Attached '${FILE}' as '${AS}' to '${PR}'" \
+ "${BRANCH}" "${CSHA}" "${METADATA[META_SHA]}"
+ say "'${FILE}' attached as '${AS}'"
+}
+
#############################################################################
## Command invocation #####################################################
#############################################################################