* [PATCH/RFC v2 8/8] contrib/subtree: Handle '--prefix' argument with a slash appended
From: Techlive Zheng @ 2013-01-14 3:52 UTC (permalink / raw)
To: git; +Cc: apenwarr, greened, Techlive Zheng
In-Reply-To: <1358135541-10349-1-git-send-email-techlivezheng@gmail.com>
'git subtree merge' will fail if the argument of '--prefix' has a slash
appended.
Signed-off-by: Techlive Zheng <techlivezheng@gmail.com>
---
contrib/subtree/git-subtree.sh | 2 +-
contrib/subtree/t/t7900-subtree.sh | 19 +++++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index d529a76..40100e5 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -83,7 +83,7 @@ while [ $# -gt 0 ]; do
--annotate) annotate="$1"; shift ;;
--no-annotate) annotate= ;;
-b) branch="$1"; shift ;;
- -P) prefix="$1"; shift ;;
+ -P) prefix="${1%/}"; shift ;;
-m) message="$1"; shift ;;
--no-prefix) prefix= ;;
--onto) onto="$1"; shift ;;
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index 232ed89..297dac4 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -238,6 +238,25 @@ test_expect_success 'merge new subproj history into subdir/ with --squash and --
)
'
+test_expect_success 'merge new subproj history into subdir/ with a slash appended to the argument of --prefix' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir/ FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir/ FETCH_HEAD &&
+ test_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''"
+ )
+'
+
#
# Tests for 'git subtree split'
#
--
1.8.1
^ permalink raw reply related
* [PATCH/RFC v2 7/8] contrib/subtree: Use %B for the split commit message
From: Techlive Zheng @ 2013-01-14 3:52 UTC (permalink / raw)
To: git; +Cc: apenwarr, greened, Techlive Zheng
In-Reply-To: <1358135541-10349-1-git-send-email-techlivezheng@gmail.com>
Use %B rather than %s%n%n%b to handle the special case of a commit that
only has a subject line. We don't want to introduce a newline after the
subject, causing generation of a new hash.
After this commit, the newly split branch might differ from the previous
one. If this is the case, --fallback option could help.
Signed-off-by: Techlive Zheng <techlivezheng@gmail.com>
Signed-off-by: David A. Greene <greened@obbligato.org>
---
contrib/subtree/git-subtree.sh | 13 ++++++++++-
contrib/subtree/git-subtree.txt | 13 +++++++++++
contrib/subtree/t/t7900-subtree.sh | 47 ++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh
index 88903c0..d529a76 100755
--- a/contrib/subtree/git-subtree.sh
+++ b/contrib/subtree/git-subtree.sh
@@ -25,6 +25,7 @@ b,branch= create a new branch from the split subtree
ignore-joins ignore prior --rejoin commits
onto= try connecting new tree to an existing one
rejoin merge the new branch back into HEAD
+fallback fallback to the obsolete commit generating mechanism
options for 'add', 'merge', 'pull' and 'push'
squash merge subtree changes as a single commit
"
@@ -45,6 +46,7 @@ ignore_joins=
annotate=
squash=
message=
+fallback=
debug()
{
@@ -92,6 +94,8 @@ while [ $# -gt 0 ]; do
--no-ignore-joins) ignore_joins= ;;
--squash) squash=1 ;;
--no-squash) squash= ;;
+ --fallback) fallback=1 ;;
+ --no-fallback) fallback= ;;
--) break ;;
*) die "Unexpected option: $opt" ;;
esac
@@ -296,7 +300,14 @@ copy_commit()
# We're going to set some environment vars here, so
# do it in a subshell to get rid of them safely later
debug copy_commit "{$1}" "{$2}" "{$3}"
- git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b' "$1" |
+
+ if [ -z "$fallback" ]; then
+ log_format='%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%B'
+ else
+ log_format='%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b'
+ fi
+
+ git log -1 --pretty=format:"$log_format" "$1" |
(
read GIT_AUTHOR_NAME
read GIT_AUTHOR_EMAIL
diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.txt
index 72be8e4..55d0575 100644
--- a/contrib/subtree/git-subtree.txt
+++ b/contrib/subtree/git-subtree.txt
@@ -254,6 +254,19 @@ OPTIONS FOR split
'--rejoin' when you split, because you don't want the
subproject's history to be part of your project anyway.
+--fallback::
+ Previously, git subtree would introduce an extra new line for
+ the commits whose commit message contains only one line.
+ This behavior has been correct. Unfortunately, for those whose
+ current split branch contains these kind of commits, git subtree
+ will generate a new split branch which differs from the existing
+ split branch in these commits. It is better to use this new
+ split branch, because its commits stay intact within the mainline.
+
+ Otherwise, the previous fault behavior could still be used with
+ this option. This option is only for a compatible purpose, newly
+ split branch should never use this option.
+
EXAMPLE 1. Add command
----------------------
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index ef83f31..232ed89 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -399,6 +399,53 @@ test_expect_success 'split subdir/ with --branch for an incompatible branch' '
)
'
+test_expect_success 'make sure commits with one line message stay intact after split' '
+ test_create_repo $test_count &&
+ test_create_repo $test_count/subproj &&
+ test_create_commit $test_count main1 &&
+ test_create_commit $test_count/subproj sub1 &&
+ (
+ cd $test_count &&
+ git fetch ./subproj master &&
+ ori_hash=$(git rev-parse FETCH_HEAD) &&
+ git branch subori FETCH_HEAD &&
+ git filter-branch --index-filter '\''git ls-files -s | sed "s-\t-&subdir/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"'\'' subori
+ git merge -m "Merge B project as our subdirectory" subori &&
+ git subtree split --prefix subdir --branch splitbr1 &&
+ new_hash_1=$(git rev-parse splitbr1) &&
+ test_equal "$ori_hash" "$new_hash_1" &&
+ git subtree split --prefix subdir --branch splitbr2 --fallback &&
+ new_hash_2=$(git rev-parse splitbr2) &&
+ test_must_fail test_equal "$ori_hash" "$new_hash_2"
+ )
+'
+
+test_expect_success 'make sure --fallback option works correctly for the existing split branch' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count"/subproj &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count"/subproj sub1 &&
+ (
+ cd $test_count &&
+ git fetch ./subproj master &&
+ ori_hash=$(git rev-parse FETCH_HEAD) &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ (
+ cd $test_count &&
+ git subtree split --prefix subdir --branch splitbr1 &&
+ git subtree split --prefix subdir --branch splitbr2 --fallback &&
+ test_must_fail test_equal "$(git rev-parse splitbr1)" "$(git rev-parse splitbr2)"
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd $test_count &&
+ test_must_fail git subtree split --prefix subdir --branch splitbr2 &&
+ git subtree split --prefix subdir --branch splitbr2 --fallback
+ )
+'
+
#
# Validity checking
#
--
1.8.1
^ permalink raw reply related
* [PATCH/RFC v2 6/8] contrib/subtree: Make each test self-contained
From: Techlive Zheng @ 2013-01-14 3:52 UTC (permalink / raw)
To: git; +Cc: apenwarr, greened, Techlive Zheng
In-Reply-To: <1358135541-10349-1-git-send-email-techlivezheng@gmail.com>
Signed-off-by: Techlive Zheng <techlivezheng@gmail.com>
---
contrib/subtree/t/t7900-subtree.sh | 865 ++++++++++++++++++++++++++-----------
1 file changed, 614 insertions(+), 251 deletions(-)
diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh
index 69bd41c..ef83f31 100755
--- a/contrib/subtree/t/t7900-subtree.sh
+++ b/contrib/subtree/t/t7900-subtree.sh
@@ -12,12 +12,6 @@ export TEST_DIRECTORY=$(pwd)/../../../t
. ../../../t/test-lib.sh
-create()
-{
- echo "$1" >"$1"
- git add "$1"
-}
-
fixnl()
{
t=""
@@ -37,11 +31,6 @@ multiline()
done
}
-undo()
-{
- git reset --hard HEAD~
-}
-
test_equal()
{
test_debug 'echo'
@@ -78,373 +67,746 @@ join_commits()
echo "$commit $all"
}
+test_create_commit() (
+ repo=$1
+ commit=$2
+ cd "$repo"
+ mkdir -p "$(dirname "$commit")"
+ echo "$commit" > "$commit"
+ git add "$commit"
+ git commit -m "$commit"
+)
+
last_commit_message()
{
git log --pretty=format:%s -1
}
-test_expect_success 'init subproj' '
- test_create_repo subproj
-'
-
-# To the subproject!
-cd subproj
-
-test_expect_success 'add sub1' '
- create sub1 &&
- git commit -m "sub1" &&
- git branch sub1 &&
- git branch -m master subproj
-'
-
-test_expect_success 'add sub2' '
- create sub2 &&
- git commit -m "sub2" &&
- git branch sub2
-'
-
-test_expect_success 'add sub3' '
- create sub3 &&
- git commit -m "sub3" &&
- git branch sub3
-'
-
-# Back to mainline
-cd ..
-
-test_expect_success 'add main4' '
- create main4 &&
- git commit -m "main4" &&
- git branch -m master mainline &&
- git branch init
-'
-
-test_expect_success 'fetch subproj history' '
- git fetch ./subproj sub1 &&
- git branch sub1 FETCH_HEAD
-'
+#
+# Tests for 'git subtree add'
+#
test_expect_success 'no pull from non-existant subtree' '
- test_must_fail git subtree pull --prefix=subdir ./subproj sub1
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ test_must_fail git subtree pull --prefix=subdir ./subproj master
+ )
'
test_expect_success 'no merge from non-existant subtree' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
test_must_fail git subtree merge --prefix=subdir FETCH_HEAD
+ )
'
test_expect_success 'add subproj as subtree into subdir/ with --prefix' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree add --prefix=subdir FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Add '\''subdir/'\'' from commit '\''$(git rev-parse FETCH_HEAD)'\''" &&
- undo
+ test_equal "$(last_commit_message)" "Add '\''subdir/'\'' from commit '\''$(git rev-parse FETCH_HEAD)'\''"
+ )
'
test_expect_success 'add subproj as subtree into subdir/ with --prefix and --message' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree add --prefix=subdir --message="Added subproject" FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Added subproject" &&
- undo
+ test_equal "$(last_commit_message)" "Added subproject"
+ )
'
test_expect_success 'add subproj as subtree into subdir/ with --prefix as -P and --message as -m' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree add -P subdir -m "Added subproject" FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Added subproject" &&
- undo
+ test_equal "$(last_commit_message)" "Added subproject"
+ )
'
test_expect_success 'add subproj as subtree into subdir/ with --squash and --prefix and --message' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree add --prefix=subdir --message="Added subproject with squash" --squash FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Added subproject with squash" &&
- undo
+ test_equal "$(last_commit_message)" "Added subproject with squash"
+ )
'
test_expect_success 'merge the added subproj again, should do nothing' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree add --prefix=subdir FETCH_HEAD &&
# this shouldn not actually do anything, since FETCH_HEAD
# is already a parent
git merge -s ours -m "merge -s -ours" FETCH_HEAD
+ )
'
-test_expect_success 'add main-sub5' '
- create subdir/main-sub5 &&
- git commit -m "main-sub5"
-'
-
-test_expect_success 'add main6' '
- create main6 &&
- git commit -m "main6 boring"
-'
-
-test_expect_success 'add main-sub7' '
- create subdir/main-sub7 &&
- git commit -m "main-sub7"
-'
-
-test_expect_success 'fetch new subproj history' '
- git fetch ./subproj sub2 &&
- git branch sub2 FETCH_HEAD
-'
+#
+# Tests for 'git subtree merge'
+#
test_expect_success 'merge new subproj history into subdir/ with --prefix' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree merge --prefix=subdir FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into mainline" &&
- undo
+ test_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''"
+ )
'
test_expect_success 'merge new subproj history into subdir/ with --prefix and --message' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree merge --prefix=subdir --message="Merged changes from subproject" FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Merged changes from subproject" &&
- undo
+ test_equal "$(last_commit_message)" "Merged changes from subproject"
+ )
'
test_expect_success 'merge new subproj history into subdir/ with --squash and --prefix and --message' '
+ test_create_repo "$test_count/subproj" &&
+ test_create_repo "$test_count" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
git subtree merge --prefix=subdir --message="Merged changes from subproject using squash" --squash FETCH_HEAD &&
- test_equal "$(last_commit_message)" "Merged changes from subproject using squash" &&
- undo
+ test_equal "$(last_commit_message)" "Merged changes from subproject using squash"
+ )
'
-test_expect_success 'merge new subproj history into subdir/' '
- git subtree merge --prefix=subdir FETCH_HEAD &&
- git branch pre-split
-'
+#
+# Tests for 'git subtree split'
+#
test_expect_success 'split requires option --prefix' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD &&
echo "You must provide the --prefix option." > expected &&
test_must_fail git subtree split > actual 2>&1 &&
test_debug "echo -n expected: " &&
test_debug "cat expected" &&
test_debug "echo -n actual: " &&
test_debug "cat actual" &&
- test_cmp expected actual &&
- rm -f expected actual
+ test_cmp expected actual
+ )
'
test_expect_success 'split requires path given by option --prefix must exist' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD &&
echo "'\''non-existent-directory'\'' does not exist; use '\''git subtree add'\''" > expected &&
test_must_fail git subtree split --prefix=non-existent-directory > actual 2>&1 &&
test_debug "echo -n expected: " &&
test_debug "cat expected" &&
test_debug "echo -n actual: " &&
test_debug "cat actual" &&
- test_cmp expected actual &&
- rm -f expected actual
+ test_cmp expected actual
+ )
'
test_expect_success 'split subdir/ with --rejoin' '
- spl1=$(git subtree split --prefix=subdir --annotate="*") &&
- git branch spl1 "$spl1" &&
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ split_hash=$(git subtree split --prefix=subdir --annotate="*") &&
git subtree split --prefix=subdir --annotate="*" --rejoin &&
- test_equal "$(last_commit_message)" "Split '\''subdir/'\'' into commit '\''$spl1'\''" &&
- undo
+ test_equal "$(last_commit_message)" "Split '\''subdir/'\'' into commit '\''$split_hash'\''"
+ )
'
test_expect_success 'split subdir/ with --rejoin and --message' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
git subtree split --prefix=subdir --message="Split & rejoin" --annotate="*" --rejoin &&
- test_equal "$(last_commit_message)" "Split & rejoin" &&
- undo
+ test_equal "$(last_commit_message)" "Split & rejoin"
+ )
'
test_expect_success 'split subdir/ with --branch' '
- spl1=$(git subtree split --prefix=subdir --message="Split & rejoin" --annotate="*" --rejoin) &&
- undo &&
- git subtree split --prefix=subdir --annotate="*" --branch splitbr1 &&
- test_equal "$(git rev-parse splitbr1)" "$spl1"
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ split_hash=$(git subtree split --prefix=subdir --annotate="*") &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br &&
+ test_equal "$(git rev-parse subproj-br)" "$split_hash"
+ )
'
test_expect_success 'split subdir/ with --branch for an existing branch' '
- spl1=$(git subtree split --prefix=subdir --annotate="*" --message="Split & rejoin" --rejoin) &&
- undo &&
- git branch splitbr2 sub1 &&
- git subtree split --prefix=subdir --annotate="*" --branch splitbr2 &&
- test_equal "$(git rev-parse splitbr2)" "$spl1"
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git branch subproj-br FETCH_HEAD &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ split_hash=$(git subtree split --prefix=subdir --annotate="*") &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br &&
+ test_equal "$(git rev-parse subproj-br)" "$split_hash"
+ )
'
test_expect_success 'split subdir/ with --branch for an incompatible branch' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git branch init HEAD &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
test_must_fail git subtree split --prefix=subdir --branch init
+ )
'
-test_expect_success 'split and rejoin' '
- git subtree split --prefix=subdir --annotate="*" --rejoin
-'
-
-test_expect_success 'add main-sub8' '
- create subdir/main-sub8 &&
- git commit -m "main-sub8"
-'
-
-# To the subproject!
-cd ./subproj
-
-test_expect_success 'merge split into subproj' '
- git fetch .. spl1 &&
- git branch spl1 FETCH_HEAD &&
- git merge FETCH_HEAD
-'
-
-test_expect_success 'add sub9' '
- create sub9 &&
- git commit -m "sub9"
-'
-
-# Back to mainline
-cd ..
-
-test_expect_success 'split for sub8' '
- spl2=$(git subtree split --prefix=subdir/ --annotate="*" --rejoin) &&
- git branch spl2 "$spl2"
-'
-
-test_expect_success 'add main-sub10' '
- create subdir/main-sub10 &&
- git commit -m "main-sub10"
-'
-
-test_expect_success 'split for sub10' '
- spl3=$(git subtree split --prefix=subdir --annotate="*" --rejoin) &&
- git branch spl3 "$spl3"
-'
-
-# To the subproject!
-cd ./subproj
-
-test_expect_success 'merge split into subproj' '
- git fetch .. spl3 &&
- git branch spl3 FETCH_HEAD &&
- git merge FETCH_HEAD &&
- git branch subproj-merge-spl3
-'
-
-chkm="main4 main6"
-chkms="main-sub10 main-sub5 main-sub7 main-sub8"
-chkms_sub=$(echo $chkms | multiline | sed 's,^,subdir/,' | fixnl)
-chks="sub1 sub2 sub3 sub9"
-chks_sub=$(echo $chks | multiline | sed 's,^,subdir/,' | fixnl)
+#
+# Validity checking
+#
test_expect_success 'make sure exactly the right set of files ends up in the subproj' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count/subproj" sub3 &&
+ test_create_commit "$test_count" subdir/main-sub3 &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD &&
+
+ chks="sub1 sub2 sub3 sub4" &&
+ chks_sub=$(echo $chks | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+ chkms="main-sub1 main-sub2 main-sub3 main-sub4" &&
+ chkms_sub=$(echo $chkms | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+
subfiles=$(git ls-files | fixnl) &&
test_equal "$subfiles" "$chkms $chks"
+ )
'
test_expect_success 'make sure the subproj *only* contains commits that affect the subdir' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count/subproj" sub3 &&
+ test_create_commit "$test_count" subdir/main-sub3 &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD &&
+
+ chks="sub1 sub2 sub3 sub4" &&
+ chks_sub=$(echo $chks | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+ chkms="main-sub1 main-sub2 main-sub3 main-sub4" &&
+ chkms_sub=$(echo $chkms | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+
allchanges=$(git log --name-only --pretty=format:"" | sort | fixnl) &&
test_equal "$allchanges" "$chkms $chks"
-'
-
-# Back to mainline
-cd ..
-
-test_expect_success 'pull from subproj' '
- git fetch ./subproj subproj-merge-spl3 &&
- git branch subproj-merge-spl3 FETCH_HEAD &&
- git subtree pull --prefix=subdir ./subproj subproj-merge-spl3
+ )
'
test_expect_success 'make sure exactly the right set of files ends up in the mainline' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count/subproj" sub3 &&
+ test_create_commit "$test_count" subdir/main-sub3 &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ (
+ cd "$test_count" &&
+ git subtree pull --prefix=subdir ./subproj master &&
+
+ chkm="main1 main2" &&
+ chks="sub1 sub2 sub3 sub4" &&
+ chks_sub=$(echo $chks | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+ chkms="main-sub1 main-sub2 main-sub3 main-sub4" &&
+ chkms_sub=$(echo $chkms | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+
mainfiles=$(git ls-files | fixnl) &&
test_equal "$mainfiles" "$chkm $chkms_sub $chks_sub"
+ )
'
test_expect_success 'make sure each filename changed exactly once in the entire history' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count/subproj" sub3 &&
+ test_create_commit "$test_count" subdir/main-sub3 &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ (
+ cd "$test_count" &&
+ git subtree pull --prefix=subdir ./subproj master &&
+
+ chkm="main1 main2" &&
+ chks="sub1 sub2 sub3 sub4" &&
+ chks_sub=$(echo $chks | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+ chkms="main-sub1 main-sub2 main-sub3 main-sub4" &&
+ chkms_sub=$(echo $chkms | multiline | sed '\''s,^,subdir/,'\'' | fixnl) &&
+
# main-sub?? and /subdir/main-sub?? both change, because those are the
# changes that were split into their own history. And subdir/sub?? never
# change, since they were *only* changed in the subtree branch.
allchanges=$(git log --name-only --pretty=format:"" | sort | fixnl) &&
test_equal "$allchanges" "$(echo $chkms $chkm $chks $chkms_sub | multiline | sort | fixnl)"
+ )
'
test_expect_success 'make sure the --rejoin commits never make it into subproj' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count/subproj" sub3 &&
+ test_create_commit "$test_count" subdir/main-sub3 &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ (
+ cd "$test_count" &&
+ git subtree pull --prefix=subdir ./subproj master &&
+
test_equal "$(git log --pretty=format:"%s" HEAD^2 | grep -i split)" ""
+ )
'
test_expect_success 'make sure no "git subtree" tagged commits make it into subproj' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ test_create_commit "$test_count" main2 &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ test_create_commit "$test_count" subdir/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count/subproj" sub3 &&
+ test_create_commit "$test_count" subdir/main-sub3 &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub4 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --annotate="*" --branch subproj-br --rejoin
+ ) &&
+ (
+ cd "$test_count/subproj" &&
+ git fetch .. subproj-br && git merge FETCH_HEAD
+ ) &&
+ (
+ cd "$test_count" &&
+ git subtree pull --prefix=subdir ./subproj master &&
+
# They are meaningless to subproj since one side of the merge refers to the mainline
test_equal "$(git log --pretty=format:"%s%n%b" HEAD^2 | grep "git-subtree.*:")" ""
+ )
'
-# prepare second pair of repositories
-mkdir test2
-cd test2
-
-test_expect_success 'init main' '
- test_create_repo main
-'
-
-cd main
-
-test_expect_success 'add main1' '
- create main1 &&
- git commit -m "main1"
-'
-
-cd ..
-
-test_expect_success 'init sub' '
- test_create_repo sub
-'
-
-cd sub
-
-test_expect_success 'add sub2' '
- create sub2 &&
- git commit -m "sub2"
-'
-
-cd ../main
-
-# check if split can find proper base without --onto
-
-test_expect_success 'add sub as subdir in main' '
- git fetch ../sub master &&
- git branch sub2 FETCH_HEAD &&
- git subtree add --prefix=subdir sub2
-'
-
-cd ../sub
-
-test_expect_success 'add sub3' '
- create sub3 &&
- git commit -m "sub3"
-'
-
-cd ../main
-
-test_expect_success 'merge from sub' '
- git fetch ../sub master &&
- git branch sub3 FETCH_HEAD &&
- git subtree merge --prefix=subdir sub3
-'
-
-test_expect_success 'add main-sub4' '
- create subdir/main-sub4 &&
- git commit -m "main-sub4"
-'
-
-test_expect_success 'split for main-sub4 without --onto' '
- git subtree split --prefix=subdir --branch mainsub4
-'
-
-# at this point, the new commit parent should be sub3 if it is not,
-# something went wrong (the "newparent" of "master~" commit should
-# have been sub3, but it was not, because its cache was not set to
-# itself)
-
-test_expect_success 'check that the commit parent is sub3' '
- test_equal "$(git log --pretty=format:%P -1 mainsub4)" "$(git rev-parse sub3)"
-'
+#
+# A new set of tests
+#
-test_expect_success 'add main-sub5' '
- mkdir subdir2 &&
- create subdir2/main-sub5 &&
- git commit -m "main-sub5"
-'
+test_expect_success 'make sure "git subtree split" find the correct parent' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git branch subproj-ref FETCH_HEAD &&
+ git subtree merge --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --branch subproj-br &&
+
+ # at this point, the new commit parent should be subproj-ref, if it is
+ # not, something went wrong (the "newparent" of "master~" commit should
+ # have been sub2, but it was not, because its cache was not set to
+ # itself)
+ test_equal "$(git log --pretty=format:%P -1 subproj-br)" "$(git rev-parse subproj-ref)"
+ )
+'
+
+test_expect_success 'split a new subtree without --onto option' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree add --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --branch subproj-br
+ ) &&
+ test_create_commit "$test_count" subdir2/main-sub2 &&
+ (
+ cd "$test_count" &&
-test_expect_success 'split for main-sub5 without --onto' '
# also test that we still can split out an entirely new subtree
# if the parent of the first commit in the tree is not empty,
# then the new subtree has accidently been attached to something
- git subtree split --prefix=subdir2 --branch mainsub5 &&
- test_equal "$(git log --pretty=format:%P -1 mainsub5)" ""
+ git subtree split --prefix=subdir2 --branch subproj2-br &&
+ test_equal "$(git log --pretty=format:%P -1 subproj2-br)" ""
+ )
'
test_expect_success 'verify one file change per commit' '
+ test_create_repo "$test_count" &&
+ test_create_repo "$test_count/subproj" &&
+ test_create_commit "$test_count" main1 &&
+ test_create_commit "$test_count/subproj" sub1 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git branch sub1 FETCH_HEAD &&
+ git subtree add --prefix=subdir sub1
+ ) &&
+ test_create_commit "$test_count/subproj" sub2 &&
+ (
+ cd "$test_count" &&
+ git fetch ./subproj master &&
+ git subtree merge --prefix=subdir FETCH_HEAD
+ ) &&
+ test_create_commit "$test_count" subdir/main-sub1 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir --branch subproj-br
+ ) &&
+ test_create_commit "$test_count" subdir2/main-sub2 &&
+ (
+ cd "$test_count" &&
+ git subtree split --prefix=subdir2 --branch subproj2-br &&
+
x= &&
git log --pretty=format:"commit: %H" | join_commits |
(
@@ -457,6 +819,7 @@ test_expect_success 'verify one file change per commit' '
done
test_equal "$x" 1
)
+ )
'
test_done
--
1.8.1
^ permalink raw reply related
* Re: [PATCH 2/8] git_remote_helpers: fix input when running under Python 3
From: Michael Haggerty @ 2013-01-14 4:48 UTC (permalink / raw)
To: John Keeping; +Cc: git, Eric S. Raymond, Felipe Contreras, Sverre Rabbelier
In-Reply-To: <20130113161724.GK4574@serenity.lan>
On 01/13/2013 05:17 PM, John Keeping wrote:
> On Sun, Jan 13, 2013 at 04:26:39AM +0100, Michael Haggerty wrote:
>> On 01/12/2013 08:23 PM, John Keeping wrote:
>>> Although 2to3 will fix most issues in Python 2 code to make it run under
>>> Python 3, it does not handle the new strict separation between byte
>>> strings and unicode strings. There is one instance in
>>> git_remote_helpers where we are caught by this.
>>>
>>> Fix it by explicitly decoding the incoming byte string into a unicode
>>> string. In this instance, use the locale under which the application is
>>> running.
>>>
>>> Signed-off-by: John Keeping <john@keeping.me.uk>
>>> ---
>>> git_remote_helpers/git/importer.py | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/git_remote_helpers/git/importer.py b/git_remote_helpers/git/importer.py
>>> index e28cc8f..6814003 100644
>>> --- a/git_remote_helpers/git/importer.py
>>> +++ b/git_remote_helpers/git/importer.py
>>> @@ -20,7 +20,7 @@ class GitImporter(object):
>>> """Returns a dictionary with refs.
>>> """
>>> args = ["git", "--git-dir=" + gitdir, "for-each-ref", "refs/heads"]
>>> - lines = check_output(args).strip().split('\n')
>>> + lines = check_output(args).decode().strip().split('\n')
>>> refs = {}
>>> for line in lines:
>>> value, name = line.split(' ')
>>>
>>
>> Won't this change cause an exception if the branch names are not all
>> valid strings in the current locale's encoding? I don't see how this
>> assumption is justified (e.g., see git-check-ref-format(1) for the rules
>> governing reference names).
>
> Yes it will. The problem is that for Python 3 we need to decode the
> byte string into a unicode string, which means we need to know what
> encoding it is.
>
> I don't think we can just say "git-for-each-ref will print refs in
> UTF-8" since AFAIK git doesn't care what encoding the refs are in - I
> suspect that's determined by the filesystem which in the end probably
> maps to whatever bytes the shell fed git when the ref was created.
>
> That's why I chose the current locale in this case. I'm hoping someone
> here will correct me if we can do better, but I don't see any way of
> avoiding choosing some encoding here if we want to support Python 3
> (which I think we will, even if we don't right now).
I'm not just trying to be a nuisance here; I'm struggling myself to
understand how a program that cares about strings-vs-bytes (e.g., a
Python3 script) should coexist with a program that doesn't (e.g., git
[1]). I think this will become a big issue if my Python version of the
commit email script ever gets integrated and then made compatible with
Python3.
You claim "for Python 3 we need to decode the byte string into a unicode
string". I understand that Python 3 strings are Unicode, but why/when
is it necessary to decode data into a Unicode string as opposed to
leaving it as a byte sequence?
In this particular case (from a cursory look over the code) it seems to
me that (1) decoding to Unicode will sometimes fail for data that git
considers valid and (2) there is no obvious reason that the data cannot
be processed as byte sequences.
Michael
[1] And it doesn't just seem that "git doesn't care about Unicode
*yet*". It seems more likely that "git will adamantly refuse to deal
with Unicode". For example, Linus is quite clearly in favor of treating
data as byte sequences in most situations:
https://plus.google.com/111049168280159033135/posts/f3fngVm174f
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* CFURLCopyResourcePropertyForKey error
From: Chase Tran @ 2013-01-14 5:06 UTC (permalink / raw)
To: git
In-Reply-To: <CAM95X3Zguz1ajaCPuztExS+2dAYBnmndkcis90aa5Mk_9+26ZA@mail.gmail.com>
I just upgraded from Mac's Lion OS to Mac's Mountain Lion OS, and when
I run gitk i get the following error:
2013-01-13 23:16:30.206 Wish[5201:707] CFURLCopyResourcePropertyForKey
failed because it was passed this URL which has no scheme:
The issue seems to have been talked about here
http://stackoverflow.com/questions/11785126/cfurlcopyresourcepropertyforkey-failed-because-it-was-passed-this-url-which-has
I then upgraded git from version 1.7.11.3 to latest 1.8.1, and issue
still persists. Does anyone know how to fix this?
Thanks,
Chase
^ permalink raw reply
* Re: [PATCH] cvsimport: rewrite to use cvsps 3.x to fix major bugs
From: Michael Haggerty @ 2013-01-14 5:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jonathan Nieder, Eric S. Raymond, git, Chris Rorvick
In-Reply-To: <7v8v7wiv3a.fsf@alter.siamese.dyndns.org>
On 01/13/2013 11:20 PM, Junio C Hamano wrote:
> After a quick survey of various distros, I think it is very unlikely
> that we will see "distros move on to newer cvsps, leaving cvsimport
> broken" situation. If anything, it is more like "distros decide to
> ignore the new cvsps, until it is made to work with cvsimport" [*1*].
A better predictor of the distros' decisions is probably which other
packages depend on cvsps. As one data point: on Debian squeeze and on
Ubuntu precise, only two packages depend on cvsps (git-cvs and
bzr-cvsps-import) and one suggests it (chora2, "a code repository
viewing component for horde framework"). So also by this standard they
are unlikely to feel a lot of pressure to update quickly to cvsps3.
> I think it is probably sensible to [...]
>
> Agreed?
Yes, I agree that what you propose is a good strategy.
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply
* [PATCH 00/14] Remove unused code from imap-send.c
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
As discussed before [1], imap-send.c was copied from isync, including
a lot of code that is not used within the git project. This patch
series rips a bunch of it out.
[1] http://comments.gmane.org/gmane.comp.version-control.git/210355
Michael Haggerty (14):
imap-send.c: remove msg_data::flags, which was always zero
imap-send.c: remove struct msg_data
iamp-send.c: remove unused struct imap_store_conf
imap-send.c: remove struct store_conf
imap-send.c: remove struct message
imap-send.c: remove some unused fields from struct store
imap-send.c: inline imap_parse_list() in imap_list()
imap-send.c: remove struct imap argument to parse_imap_list_l()
imap-send.c: remove namespace fields from struct imap
imap-send.c: remove unused field imap_store::trashnc
imap-send.c: simplify logic in lf_to_crlf()
imap-send.c: use struct imap_store instead of struct store
imap-send.c: remove unused field imap_store::uidvalidity
imap-send.c: fold struct store into struct imap_store
imap-send.c | 286 +++++++++---------------------------------------------------
1 file changed, 39 insertions(+), 247 deletions(-)
--
1.8.0.3
^ permalink raw reply
* [PATCH 02/14] imap-send.c: remove struct msg_data
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
Now that its flags member has been deleted, all that is left is a
strbuf. So use a strbuf directly.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 451d502..a8cb66a 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -68,10 +68,6 @@ struct store {
int recent; /* # of recent messages - don't trust this beyond the initial read */
};
-struct msg_data {
- struct strbuf data;
-};
-
static const char imap_send_usage[] = "git imap-send < <mbox>";
#undef DRV_OK
@@ -1279,7 +1275,7 @@ static void lf_to_crlf(struct strbuf *msg)
* Store msg to IMAP. Also detach and free the data from msg->data,
* leaving msg->data empty.
*/
-static int imap_store_msg(struct store *gctx, struct msg_data *msg)
+static int imap_store_msg(struct store *gctx, struct strbuf *msg)
{
struct imap_store *ctx = (struct imap_store *)gctx;
struct imap *imap = ctx->imap;
@@ -1287,11 +1283,11 @@ static int imap_store_msg(struct store *gctx, struct msg_data *msg)
const char *prefix, *box;
int ret;
- lf_to_crlf(&msg->data);
+ lf_to_crlf(msg);
memset(&cb, 0, sizeof(cb));
- cb.dlen = msg->data.len;
- cb.data = strbuf_detach(&msg->data, NULL);
+ cb.dlen = msg->len;
+ cb.data = strbuf_detach(msg, NULL);
box = gctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
@@ -1449,7 +1445,7 @@ static int git_imap_config(const char *key, const char *val, void *cb)
int main(int argc, char **argv)
{
struct strbuf all_msgs = STRBUF_INIT;
- struct msg_data msg = {STRBUF_INIT};
+ struct strbuf msg = STRBUF_INIT;
struct store *ctx = NULL;
int ofs = 0;
int r;
@@ -1511,10 +1507,10 @@ int main(int argc, char **argv)
unsigned percent = n * 100 / total;
fprintf(stderr, "%4u%% (%d/%d) done\r", percent, n, total);
- if (!split_msg(&all_msgs, &msg.data, &ofs))
+ if (!split_msg(&all_msgs, &msg, &ofs))
break;
if (server.use_html)
- wrap_in_html(&msg.data);
+ wrap_in_html(&msg);
r = imap_store_msg(ctx, &msg);
if (r != DRV_OK)
break;
--
1.8.0.3
^ permalink raw reply related
* [PATCH 04/14] imap-send.c: remove struct store_conf
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
It was never used.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index d675e70..3177361 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -33,15 +33,6 @@ typedef void *SSL;
#include <openssl/hmac.h>
#endif
-struct store_conf {
- char *name;
- const char *path; /* should this be here? its interpretation is driver-specific */
- char *map_inbox;
- char *trash;
- unsigned max_size; /* off_t is overkill */
- unsigned trash_remote_new:1, trash_only_new:1;
-};
-
/* For message->status */
#define M_RECENT (1<<0) /* unsyncable flag; maildir_* depend on this being 1<<0 */
#define M_DEAD (1<<1) /* expunged */
@@ -55,8 +46,6 @@ struct message {
};
struct store {
- struct store_conf *conf; /* foreign */
-
/* currently open mailbox */
const char *name; /* foreign! maybe preset? */
char *path; /* own */
--
1.8.0.3
^ permalink raw reply related
* [PATCH 06/14] imap-send.c: remove some unused fields from struct store
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index a47008b..fe2bfab 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -36,12 +36,7 @@ typedef void *SSL;
struct store {
/* currently open mailbox */
const char *name; /* foreign! maybe preset? */
- char *path; /* own */
int uidvalidity;
- unsigned char opts; /* maybe preset? */
- /* note that the following do _not_ reflect stats from msgs, but mailbox totals */
- int count; /* # of messages */
- int recent; /* # of recent messages - don't trust this beyond the initial read */
};
static const char imap_send_usage[] = "git imap-send < <mbox>";
@@ -772,13 +767,10 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
!strcmp("NO", arg) || !strcmp("BYE", arg)) {
if ((resp = parse_response_code(ctx, NULL, cmd)) != RESP_OK)
return resp;
- } else if (!strcmp("CAPABILITY", arg))
+ } else if (!strcmp("CAPABILITY", arg)) {
parse_capability(imap, cmd);
- else if ((arg1 = next_arg(&cmd))) {
- if (!strcmp("EXISTS", arg1))
- ctx->gen.count = atoi(arg);
- else if (!strcmp("RECENT", arg1))
- ctx->gen.recent = atoi(arg);
+ } else if ((arg1 = next_arg(&cmd))) {
+ /* unused */
} else {
fprintf(stderr, "IMAP error: unable to parse untagged response\n");
return RESP_BAD;
@@ -1254,7 +1246,6 @@ static int imap_store_msg(struct store *gctx, struct strbuf *msg)
imap->caps = imap->rcaps;
if (ret != DRV_OK)
return ret;
- gctx->count++;
return DRV_OK;
}
--
1.8.0.3
^ permalink raw reply related
* [PATCH 05/14] imap-send.c: remove struct message
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
It was never used.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 26 --------------------------
1 file changed, 26 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 3177361..a47008b 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -33,23 +33,10 @@ typedef void *SSL;
#include <openssl/hmac.h>
#endif
-/* For message->status */
-#define M_RECENT (1<<0) /* unsyncable flag; maildir_* depend on this being 1<<0 */
-#define M_DEAD (1<<1) /* expunged */
-#define M_FLAGS (1<<2) /* flags fetched */
-
-struct message {
- struct message *next;
- size_t size; /* zero implies "not fetched" */
- int uid;
- unsigned char flags, status;
-};
-
struct store {
/* currently open mailbox */
const char *name; /* foreign! maybe preset? */
char *path; /* own */
- struct message *msgs; /* own */
int uidvalidity;
unsigned char opts; /* maybe preset? */
/* note that the following do _not_ reflect stats from msgs, but mailbox totals */
@@ -74,8 +61,6 @@ static void imap_warn(const char *, ...);
static char *next_arg(char **);
-static void free_generic_messages(struct message *);
-
__attribute__((format (printf, 3, 4)))
static int nfsnprintf(char *buf, int blen, const char *fmt, ...);
@@ -447,16 +432,6 @@ static char *next_arg(char **s)
return ret;
}
-static void free_generic_messages(struct message *msgs)
-{
- struct message *tmsg;
-
- for (; msgs; msgs = tmsg) {
- tmsg = msgs->next;
- free(msgs);
- }
-}
-
static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
{
int ret;
@@ -914,7 +889,6 @@ static void imap_close_server(struct imap_store *ictx)
static void imap_close_store(struct store *ctx)
{
imap_close_server((struct imap_store *)ctx);
- free_generic_messages(ctx->msgs);
free(ctx);
}
--
1.8.0.3
^ permalink raw reply related
* [PATCH 08/14] imap-send.c: remove struct imap argument to parse_imap_list_l()
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
It was always set to NULL.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 39 +++------------------------------------
1 file changed, 3 insertions(+), 36 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 452e73e..5238c74 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -578,11 +578,10 @@ static void free_list(struct imap_list *list)
}
}
-static int parse_imap_list_l(struct imap *imap, char **sp, struct imap_list **curp, int level)
+static int parse_imap_list_l(char **sp, struct imap_list **curp, int level)
{
struct imap_list *cur;
char *s = *sp, *p;
- int n, bytes;
for (;;) {
while (isspace((unsigned char)*s))
@@ -598,39 +597,7 @@ static int parse_imap_list_l(struct imap *imap, char **sp, struct imap_list **cu
/* sublist */
s++;
cur->val = LIST;
- if (parse_imap_list_l(imap, &s, &cur->child, level + 1))
- goto bail;
- } else if (imap && *s == '{') {
- /* literal */
- bytes = cur->len = strtol(s + 1, &s, 10);
- if (*s != '}')
- goto bail;
-
- s = cur->val = xmalloc(cur->len);
-
- /* dump whats left over in the input buffer */
- n = imap->buf.bytes - imap->buf.offset;
-
- if (n > bytes)
- /* the entire message fit in the buffer */
- n = bytes;
-
- memcpy(s, imap->buf.buf + imap->buf.offset, n);
- s += n;
- bytes -= n;
-
- /* mark that we used part of the buffer */
- imap->buf.offset += n;
-
- /* now read the rest of the message */
- while (bytes > 0) {
- if ((n = socket_read(&imap->buf.sock, s, bytes)) <= 0)
- goto bail;
- s += n;
- bytes -= n;
- }
-
- if (buffer_gets(&imap->buf, &s))
+ if (parse_imap_list_l(&s, &cur->child, level + 1))
goto bail;
} else if (*s == '"') {
/* quoted string */
@@ -673,7 +640,7 @@ static struct imap_list *parse_list(char **sp)
{
struct imap_list *head;
- if (!parse_imap_list_l(NULL, sp, &head, 0))
+ if (!parse_imap_list_l(sp, &head, 0))
return head;
free_list(head);
return NULL;
--
1.8.0.3
^ permalink raw reply related
* [PATCH 10/14] imap-send.c: remove unused field imap_store::trashnc
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 9616e80..70abe9b 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -127,7 +127,6 @@ struct imap_store {
int uidvalidity;
struct imap *imap;
const char *prefix;
- unsigned /*currentnc:1,*/ trashnc:1;
};
struct imap_cmd_cb {
@@ -1079,7 +1078,6 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)
} /* !preauth */
ctx->prefix = "";
- ctx->trashnc = 1;
return (struct store *)ctx;
bail:
--
1.8.0.3
^ permalink raw reply related
* [PATCH 13/14] imap-send.c: remove unused field imap_store::uidvalidity
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
I suspect that the existence of both imap_store::uidvalidity and
store::uidvalidity was an accident.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/imap-send.c b/imap-send.c
index 31fdbf3..4d24faf 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -124,7 +124,6 @@ struct imap {
struct imap_store {
struct store gen;
- int uidvalidity;
struct imap *imap;
const char *prefix;
};
--
1.8.0.3
^ permalink raw reply related
* [PATCH 14/14] imap-send.c: fold struct store into struct imap_store
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 4d24faf..1b665bb 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -33,12 +33,6 @@ typedef void *SSL;
#include <openssl/hmac.h>
#endif
-struct store {
- /* currently open mailbox */
- const char *name; /* foreign! maybe preset? */
- int uidvalidity;
-};
-
static const char imap_send_usage[] = "git imap-send < <mbox>";
#undef DRV_OK
@@ -123,7 +117,9 @@ struct imap {
};
struct imap_store {
- struct store gen;
+ /* currently open mailbox */
+ const char *name; /* foreign! maybe preset? */
+ int uidvalidity;
struct imap *imap;
const char *prefix;
};
@@ -618,7 +614,7 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
*p++ = 0;
arg = next_arg(&s);
if (!strcmp("UIDVALIDITY", arg)) {
- if (!(arg = next_arg(&s)) || !(ctx->gen.uidvalidity = atoi(arg))) {
+ if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg))) {
fprintf(stderr, "IMAP error: malformed UIDVALIDITY status\n");
return RESP_BAD;
}
@@ -636,7 +632,7 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb,
for (; isspace((unsigned char)*p); p++);
fprintf(stderr, "*** IMAP ALERT *** %s\n", p);
} else if (cb && cb->ctx && !strcmp("APPENDUID", arg)) {
- if (!(arg = next_arg(&s)) || !(ctx->gen.uidvalidity = atoi(arg)) ||
+ if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg)) ||
!(arg = next_arg(&s)) || !(*(int *)cb->ctx = atoi(arg))) {
fprintf(stderr, "IMAP error: malformed APPENDUID status\n");
return RESP_BAD;
@@ -1124,7 +1120,7 @@ static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)
cb.dlen = msg->len;
cb.data = strbuf_detach(msg, NULL);
- box = ctx->gen.name;
+ box = ctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
cb.create = 0;
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\"", prefix, box);
@@ -1336,7 +1332,7 @@ int main(int argc, char **argv)
}
fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
- ctx->gen.name = imap_folder;
+ ctx->name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;
--
1.8.0.3
^ permalink raw reply related
* [PATCH 01/14] imap-send.c: remove msg_data::flags, which was always zero
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
This removes the need for function imap_make_flags(), so delete it,
too.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 40 +++-------------------------------------
1 file changed, 3 insertions(+), 37 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index e521e2f..451d502 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -70,7 +70,6 @@ struct store {
struct msg_data {
struct strbuf data;
- unsigned char flags;
};
static const char imap_send_usage[] = "git imap-send < <mbox>";
@@ -225,14 +224,6 @@ static const char *cap_list[] = {
static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd);
-static const char *Flags[] = {
- "Draft",
- "Flagged",
- "Answered",
- "Seen",
- "Deleted",
-};
-
#ifndef NO_OPENSSL
static void ssl_socket_perror(const char *func)
{
@@ -1246,23 +1237,6 @@ bail:
return NULL;
}
-static int imap_make_flags(int flags, char *buf)
-{
- const char *s;
- unsigned i, d;
-
- for (i = d = 0; i < ARRAY_SIZE(Flags); i++)
- if (flags & (1 << i)) {
- buf[d++] = ' ';
- buf[d++] = '\\';
- for (s = Flags[i]; *s; s++)
- buf[d++] = *s;
- }
- buf[0] = '(';
- buf[d++] = ')';
- return d;
-}
-
static void lf_to_crlf(struct strbuf *msg)
{
size_t new_len;
@@ -1311,8 +1285,7 @@ static int imap_store_msg(struct store *gctx, struct msg_data *msg)
struct imap *imap = ctx->imap;
struct imap_cmd_cb cb;
const char *prefix, *box;
- int ret, d;
- char flagstr[128];
+ int ret;
lf_to_crlf(&msg->data);
memset(&cb, 0, sizeof(cb));
@@ -1320,17 +1293,10 @@ static int imap_store_msg(struct store *gctx, struct msg_data *msg)
cb.dlen = msg->data.len;
cb.data = strbuf_detach(&msg->data, NULL);
- d = 0;
- if (msg->flags) {
- d = imap_make_flags(msg->flags, flagstr);
- flagstr[d++] = ' ';
- }
- flagstr[d] = 0;
-
box = gctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
cb.create = 0;
- ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr);
+ ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\"", prefix, box);
imap->caps = imap->rcaps;
if (ret != DRV_OK)
return ret;
@@ -1483,7 +1449,7 @@ static int git_imap_config(const char *key, const char *val, void *cb)
int main(int argc, char **argv)
{
struct strbuf all_msgs = STRBUF_INIT;
- struct msg_data msg = {STRBUF_INIT, 0};
+ struct msg_data msg = {STRBUF_INIT};
struct store *ctx = NULL;
int ofs = 0;
int r;
--
1.8.0.3
^ permalink raw reply related
* [PATCH 03/14] iamp-send.c: remove unused struct imap_store_conf
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index a8cb66a..d675e70 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -130,11 +130,6 @@ static struct imap_server_conf server = {
NULL, /* auth_method */
};
-struct imap_store_conf {
- struct store_conf gen;
- struct imap_server_conf *server;
-};
-
#define NIL (void *)0x1
#define LIST (void *)0x2
--
1.8.0.3
^ permalink raw reply related
* [PATCH 07/14] imap-send.c: inline imap_parse_list() in imap_list()
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
The function is only called from here.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index fe2bfab..452e73e 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -669,21 +669,16 @@ bail:
return -1;
}
-static struct imap_list *parse_imap_list(struct imap *imap, char **sp)
+static struct imap_list *parse_list(char **sp)
{
struct imap_list *head;
- if (!parse_imap_list_l(imap, sp, &head, 0))
+ if (!parse_imap_list_l(NULL, sp, &head, 0))
return head;
free_list(head);
return NULL;
}
-static struct imap_list *parse_list(char **sp)
-{
- return parse_imap_list(NULL, sp);
-}
-
static void parse_capability(struct imap *imap, char *cmd)
{
char *arg;
--
1.8.0.3
^ permalink raw reply related
* [PATCH 12/14] imap-send.c: use struct imap_store instead of struct store
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
In fact, all struct store instances are upcasts of struct imap_store
anyway, so stop making the distinction.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 3167dcc..31fdbf3 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -781,9 +781,9 @@ static void imap_close_server(struct imap_store *ictx)
free(imap);
}
-static void imap_close_store(struct store *ctx)
+static void imap_close_store(struct imap_store *ctx)
{
- imap_close_server((struct imap_store *)ctx);
+ imap_close_server(ctx);
free(ctx);
}
@@ -868,7 +868,7 @@ static int auth_cram_md5(struct imap_store *ctx, struct imap_cmd *cmd, const cha
return 0;
}
-static struct store *imap_open_store(struct imap_server_conf *srvc)
+static struct imap_store *imap_open_store(struct imap_server_conf *srvc)
{
struct imap_store *ctx;
struct imap *imap;
@@ -1078,10 +1078,10 @@ static struct store *imap_open_store(struct imap_server_conf *srvc)
} /* !preauth */
ctx->prefix = "";
- return (struct store *)ctx;
+ return ctx;
bail:
- imap_close_store(&ctx->gen);
+ imap_close_store(ctx);
return NULL;
}
@@ -1112,9 +1112,8 @@ static void lf_to_crlf(struct strbuf *msg)
* Store msg to IMAP. Also detach and free the data from msg->data,
* leaving msg->data empty.
*/
-static int imap_store_msg(struct store *gctx, struct strbuf *msg)
+static int imap_store_msg(struct imap_store *ctx, struct strbuf *msg)
{
- struct imap_store *ctx = (struct imap_store *)gctx;
struct imap *imap = ctx->imap;
struct imap_cmd_cb cb;
const char *prefix, *box;
@@ -1126,7 +1125,7 @@ static int imap_store_msg(struct store *gctx, struct strbuf *msg)
cb.dlen = msg->len;
cb.data = strbuf_detach(msg, NULL);
- box = gctx->name;
+ box = ctx->gen.name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
cb.create = 0;
ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\"", prefix, box);
@@ -1282,7 +1281,7 @@ int main(int argc, char **argv)
{
struct strbuf all_msgs = STRBUF_INIT;
struct strbuf msg = STRBUF_INIT;
- struct store *ctx = NULL;
+ struct imap_store *ctx = NULL;
int ofs = 0;
int r;
int total, n = 0;
@@ -1338,7 +1337,7 @@ int main(int argc, char **argv)
}
fprintf(stderr, "sending %d message%s\n", total, (total != 1) ? "s" : "");
- ctx->name = imap_folder;
+ ctx->gen.name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;
--
1.8.0.3
^ permalink raw reply related
* [PATCH 09/14] imap-send.c: remove namespace fields from struct imap
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
They are unused, and their removal means that a bunch of list-related
infrastructure can be disposed of.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 74 +++++++------------------------------------------------------
1 file changed, 8 insertions(+), 66 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 5238c74..9616e80 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -99,15 +99,6 @@ static struct imap_server_conf server = {
NULL, /* auth_method */
};
-#define NIL (void *)0x1
-#define LIST (void *)0x2
-
-struct imap_list {
- struct imap_list *next, *child;
- char *val;
- int len;
-};
-
struct imap_socket {
int fd[2];
SSL *ssl;
@@ -124,7 +115,6 @@ struct imap_cmd;
struct imap {
int uidnext; /* from SELECT responses */
- struct imap_list *ns_personal, *ns_other, *ns_shared; /* NAMESPACE info */
unsigned caps, rcaps; /* CAPABILITY results */
/* command queue */
int nexttag, num_in_progress, literal_pending;
@@ -554,34 +544,9 @@ static int imap_exec_m(struct imap_store *ctx, struct imap_cmd_cb *cb,
}
}
-static int is_atom(struct imap_list *list)
-{
- return list && list->val && list->val != NIL && list->val != LIST;
-}
-
-static int is_list(struct imap_list *list)
-{
- return list && list->val == LIST;
-}
-
-static void free_list(struct imap_list *list)
-{
- struct imap_list *tmp;
-
- for (; list; list = tmp) {
- tmp = list->next;
- if (is_list(list))
- free_list(list->child);
- else if (is_atom(list))
- free(list->val);
- free(list);
- }
-}
-
-static int parse_imap_list_l(char **sp, struct imap_list **curp, int level)
+static int skip_imap_list_l(char **sp, int level)
{
- struct imap_list *cur;
- char *s = *sp, *p;
+ char *s = *sp;
for (;;) {
while (isspace((unsigned char)*s))
@@ -590,36 +555,23 @@ static int parse_imap_list_l(char **sp, struct imap_list **curp, int level)
s++;
break;
}
- *curp = cur = xmalloc(sizeof(*cur));
- curp = &cur->next;
- cur->val = NULL; /* for clean bail */
if (*s == '(') {
/* sublist */
s++;
- cur->val = LIST;
- if (parse_imap_list_l(&s, &cur->child, level + 1))
+ if (skip_imap_list_l(&s, level + 1))
goto bail;
} else if (*s == '"') {
/* quoted string */
s++;
- p = s;
for (; *s != '"'; s++)
if (!*s)
goto bail;
- cur->len = s - p;
s++;
- cur->val = xmemdupz(p, cur->len);
} else {
/* atom */
- p = s;
for (; *s && !isspace((unsigned char)*s); s++)
if (level && *s == ')')
break;
- cur->len = s - p;
- if (cur->len == 3 && !memcmp("NIL", p, 3))
- cur->val = NIL;
- else
- cur->val = xmemdupz(p, cur->len);
}
if (!level)
@@ -628,22 +580,15 @@ static int parse_imap_list_l(char **sp, struct imap_list **curp, int level)
goto bail;
}
*sp = s;
- *curp = NULL;
return 0;
bail:
- *curp = NULL;
return -1;
}
-static struct imap_list *parse_list(char **sp)
+static void skip_list(char **sp)
{
- struct imap_list *head;
-
- if (!parse_imap_list_l(sp, &head, 0))
- return head;
- free_list(head);
- return NULL;
+ skip_imap_list_l(sp, 0);
}
static void parse_capability(struct imap *imap, char *cmd)
@@ -722,9 +667,9 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
}
if (!strcmp("NAMESPACE", arg)) {
- imap->ns_personal = parse_list(&cmd);
- imap->ns_other = parse_list(&cmd);
- imap->ns_shared = parse_list(&cmd);
+ skip_list(&cmd);
+ skip_list(&cmd);
+ skip_list(&cmd);
} else if (!strcmp("OK", arg) || !strcmp("BAD", arg) ||
!strcmp("NO", arg) || !strcmp("BYE", arg)) {
if ((resp = parse_response_code(ctx, NULL, cmd)) != RESP_OK)
@@ -834,9 +779,6 @@ static void imap_close_server(struct imap_store *ictx)
imap_exec(ictx, NULL, "LOGOUT");
socket_shutdown(&imap->buf.sock);
}
- free_list(imap->ns_personal);
- free_list(imap->ns_other);
- free_list(imap->ns_shared);
free(imap);
}
--
1.8.0.3
^ permalink raw reply related
* [PATCH 11/14] imap-send.c: simplify logic in lf_to_crlf()
From: Michael Haggerty @ 2013-01-14 5:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Jeff King, git, Michael Haggerty
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
imap-send.c | 31 ++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 70abe9b..3167dcc 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1089,36 +1089,21 @@ static void lf_to_crlf(struct strbuf *msg)
{
size_t new_len;
char *new;
- int i, j, lfnum = 0;
+ int i, j = 0, lfnum = 0;
+ char lastc;
- if (msg->buf[0] == '\n')
- lfnum++;
- for (i = 1; i < msg->len; i++) {
- if (msg->buf[i - 1] != '\r' && msg->buf[i] == '\n')
+ for (i = 0, lastc = '\0'; i < msg->len; i++) {
+ if (msg->buf[i] == '\n' && lastc != '\r')
lfnum++;
+ lastc = msg->buf[i];
}
new_len = msg->len + lfnum;
new = xmalloc(new_len + 1);
- if (msg->buf[0] == '\n') {
- new[0] = '\r';
- new[1] = '\n';
- i = 1;
- j = 2;
- } else {
- new[0] = msg->buf[0];
- i = 1;
- j = 1;
- }
- for ( ; i < msg->len; i++) {
- if (msg->buf[i] != '\n') {
- new[j++] = msg->buf[i];
- continue;
- }
- if (msg->buf[i - 1] != '\r')
+ for (i = 0, lastc = '\0'; i < msg->len; i++) {
+ if (msg->buf[i] == '\n' && lastc != '\r')
new[j++] = '\r';
- /* otherwise it already had CR before */
- new[j++] = '\n';
+ lastc = new[j++] = msg->buf[i];
}
strbuf_attach(msg, new, new_len, new_len + 1);
}
--
1.8.0.3
^ permalink raw reply related
* Re: [PATCH 01/14] imap-send.c: remove msg_data::flags, which was always zero
From: Jonathan Nieder @ 2013-01-14 5:57 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Junio C Hamano, Jeff King, git
In-Reply-To: <1358141566-26081-2-git-send-email-mhagger@alum.mit.edu>
Hi,
Michael Haggerty wrote:
> This removes the need for function imap_make_flags(), so delete it,
> too.
[...]
> --- a/imap-send.c
> +++ b/imap-send.c
[...]
> box = gctx->name;
> prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
> cb.create = 0;
> - ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr);
> + ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\"", prefix, box);
Before this change, the command is
"APPEND" SP mailbox SP "{" msglen "}" CRLF
. After this change, it leaves out the space before the brace. If I
understand RFC3501 correctly, the space is required. Intentional?
With the below squashed in,
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
diff --git i/imap-send.c w/imap-send.c
index 451d5027..f1c8f5a5 100644
--- i/imap-send.c
+++ w/imap-send.c
@@ -1296,7 +1296,7 @@ static int imap_store_msg(struct store *gctx, struct msg_data *msg)
box = gctx->name;
prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
cb.create = 0;
- ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\"", prefix, box);
+ ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" ", prefix, box);
imap->caps = imap->rcaps;
if (ret != DRV_OK)
return ret;
^ permalink raw reply related
* Re: [PATCH 00/14] Remove unused code from imap-send.c
From: Jeff King @ 2013-01-14 6:06 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Junio C Hamano, git
In-Reply-To: <1358141566-26081-1-git-send-email-mhagger@alum.mit.edu>
On Mon, Jan 14, 2013 at 06:32:32AM +0100, Michael Haggerty wrote:
> As discussed before [1], imap-send.c was copied from isync, including
> a lot of code that is not used within the git project. This patch
> series rips a bunch of it out.
Thanks, this looks like a good direction.
I did not notice any problems reading through the patches, but my brain
is frazzled from a day of flying. I missed the problem Jonathan noticed.
:)
Some of the things you are removing are for advanced IMAP features that
imap-send does not need. In theory, somebody might extend it to use them
in the future. But since it has not seen any active feature development
in years, and since anybody could resurrect the code by reverting your
commits, I don't think it is a big risk.
I suspect you could go even further in ripping things out (e.g., I do
not think a server will generate an untagged namespace response at all
if we do not ask for it by issuing a namespace command). But you've
certainly grabbed the low-hanging fruit that can mostly be verified by
the compiler, and I don't know if it's worth the effort to go much
further, as it would require a lot of manual verification (and
understanding of IMAP, which will rot your brain).
-Peff
^ permalink raw reply
* Announcing git-reparent
From: Mark Lodato @ 2013-01-14 6:15 UTC (permalink / raw)
To: git list
I threw together a small utility called "git-reparent", available on GitHub at:
https://github.com/MarkLodato/git-reparent
I welcome any comments or suggestions. To make discussion easier,
I've copied the README and code below.
--- 8< ---
NAME
====
git-reparent - Recommit HEAD with a new set of parents.
SYNOPSIS
========
``git reparent [OPTIONS] ((-p <parent>)... | --no-parent)``
DESCRIPTION
===========
Create a new commit object that has the same tree and commit message as HEAD
but with a different set of parents. If ``--no-reset`` is given, the full
object id of this commit is printed and the program exits; otherwise, ``git
reset`` is used to update HEAD and the current branch to this new commit.
This command can be used to manually shape the history of a repository.
Whereas ``git rebase`` moves around *diffs*, ``git reparent`` moves around
*snapshots*. See EXAMPLES for a reason why you might want to use this
command.
OPTIONS
=======
-h, --help show the help
-e, --edit edit the commit message in an editor first
-m, --message <message> use the given message instead of that of HEAD
-p, --parent <commit> new parent to use; may be given multiple times
--no-parent create a parentless commit
-q, --quiet be quiet; only report errors
--no-reset print the new object id instead of updating HEAD
INSTALLATION
============
Make executable and place somewhere in your $PATH.
EXAMPLES
========
Reparenting the tip of a branch
-------------------------------
Suppose we create some commit *B* and then accidentally pass the ``--amend``
flag when creating new commit *C*, resulting in the following history::
B
/
...---A---C (HEAD)
What we really wanted was one linear history, ``...---A--B--C``. If we
were to use ``git rebase`` or ``git cherry-pick`` to reconstruct the history,
this would try to apply the *diff* of *A..C* onto *B*, which might fail.
Instead, what we really want to do is use the exact message and tree from *C*
but with parent *B* instead of *A*. To do this, we run ::
$ git reparent -p B
where the name *B* can be found by running ``git reflog`` and looking for the
first "commit (amend)". The resulting history is now just what we wanted::
C
/
...---A---B---C' (HEAD)
Reparenting an inner commit
---------------------------
We can also update the parents of a commit other than the most recent.
Suppose that we want to perform a rebase-like operation, moving *master* onto
*origin/master*, but we want to completely ignore any changes made in the
remote branch. That is, our history currently looks like this::
B---C (master, HEAD)
/
...---A---D---E (origin/master)
and we want to make it look like this::
B---C (origin/master)
/ /
...---A---D---E---B'---C' (master, HEAD)
We can accomplish this by using ``git rebase --interactive`` along with ``git
reparent``::
$ git rebase -i A
# select the "edit" command for commit B
# git rebase will dump us out at commit B
$ git reparent -p origin/master
$ git rebase --continue
Now the history will look as desired, and the trees, commit messages, and
authors of *B'* and *C'* will be identical to those of *B* and *C*,
respectively.
SEE ALSO
========
git-filter-branch(1) combined with either git grafts or git-replace(1) can be
used to achieve the same effect
git-rebase(1) can be used to re-apply the *diffs* of the current branch to
another
AUTHOR
======
Mark Lodato <lodatom@gmail.com>
--- 8< ---
#!/bin/sh
# Copyright (c) Mark Lodato, 2013
OPTIONS_SPEC="\
git reparent [OPTIONS] ((-p <parent>)... | --no-parent)
Recommit HEAD with a new set of parents.
--
h,help show the help
e,edit edit the commit message in an editor first
m,message= use the given message instead of that of HEAD
p,parent=! new parent to use; may be given multiple times
no-parent! create a parentless commit
q,quiet be quiet; only report errors
reset* default behavior
no-reset! print the new object id instead of updating HEAD
"
SUBDIRECTORY_OK=Yes
. "$(git --exec-path)/git-sh-setup" || exit $?
require_clean_work_tree reparent "Please commit or stash them first."
# Location of the temporary message.
msg_file="$GIT_DIR/reparent-msg"
die_with_usage() {
echo "error: $1" >&2
usage
}
edit=
message=
no_parent=
no_reset=
parent_flags=
quiet=
while [ $# -gt 0 ]; do
case "$1" in
-p)
[ $# -eq 0 ] && die_with_usage "-p requires an argument"
shift
parent_flags="$parent_flags$(git rev-parse --sq-quote -p "$1")"
;;
--no-parent) no_parent=1 ;;
-e) edit=1 ;;
--no-edit) edit= ;;
-m) message="$2"; shift ;;
--no-message)message= ;;
-q) quiet=-q ;;
--no-quiet) quiet= ;;
--reset) no_reset= ;;
--no-reset) no_reset=1 ;;
--) shift; break ;;
*) die "internal error: unknown flag $1" ;;
esac
shift
done
[ $# -gt 0 ] && \
die_with_usage "no positional arguments expected"
[ -z "$no_parent" -a -z "$parent_flags" ] && \
die_with_usage "either -p or --no-parent is required"
[ -n "$no_parent" -a -n "$parent_flags" ] && \
die_with_usage "-p and --no-parent are mutually exclusive"
# Create the commit.
if [ -n "$message" ]; then
echo "$message" > "$msg_file"
else
git cat-file commit HEAD | sed "1,/^$/d" > "$msg_file"
fi
if [ -n "$edit" ]; then
# TODO: use the normal `git commit` comment stripping stuff
git_editor "$msg_file" || die "no editor configured"
[ -s "$msg_file" ] || die "aborting due to empty commit message"
fi
eval "$(get_author_ident_from_commit HEAD)"
old_head="$(git rev-parse --short HEAD)" || exit $?
new_head="$(eval "git commit-tree HEAD: $parent_flags" '< $msg_file')" || \
exit $?
rm "$msg_file"
# Print out the commit if --no-reset; otherwise update HEAD.
if [ -n "$no_reset" ]; then
echo "$new_head"
else
set_reflog_action reparent
git reset $quiet "$new_head" || exit $?
new_abbrev="$(git rev-parse --short HEAD)" || exit $?
[ -z "$quiet" ] && echo "Moved HEAD to $new_abbrev (was $old_head)"
fi
^ permalink raw reply
* Re: [PATCH 06/14] imap-send.c: remove some unused fields from struct store
From: Jonathan Nieder @ 2013-01-14 6:19 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Junio C Hamano, Jeff King, git
In-Reply-To: <1358141566-26081-7-git-send-email-mhagger@alum.mit.edu>
Michael Haggerty wrote:
> --- a/imap-send.c
> +++ b/imap-send.c
[...]
> @@ -772,13 +767,10 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd)
> !strcmp("NO", arg) || !strcmp("BYE", arg)) {
> if ((resp = parse_response_code(ctx, NULL, cmd)) != RESP_OK)
> return resp;
> - } else if (!strcmp("CAPABILITY", arg))
> + } else if (!strcmp("CAPABILITY", arg)) {
> parse_capability(imap, cmd);
> - else if ((arg1 = next_arg(&cmd))) {
> - if (!strcmp("EXISTS", arg1))
> - ctx->gen.count = atoi(arg);
> - else if (!strcmp("RECENT", arg1))
> - ctx->gen.recent = atoi(arg);
> + } else if ((arg1 = next_arg(&cmd))) {
> + /* unused */
Neat. Let me try to understand what was going on here:
When opening a mailbox with the SELECT command, an IMAP server
responds with tagged data indicating how many messages exist and how
many are marked Recent. But git imap-send never reads mailboxes and
in particular never uses the SELECT command, so there is no need for
us to parse or record such responses.
Out of paranoia we are keeping the parsing for now, but the parsed
response is unused, hence the comment above.
If I've understood correctly so far (a big assumption), I still am not
sure what it would mean if we hit this ((arg1 = next_arg(&cmd))) case.
Does it mean:
A. The server has gone haywire and given a tagged response where
one is not allowed, but let's tolerate it because we always have
done so? Or
B. This is a perfectly normal response to some of the commands we
send, and we have always been deliberately ignoring it because it
is not important for what imap-send does?
Curious,
Jonathan
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox