From 35ebfd6a0cd71795c4fa510b99e55ad89fb654f1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 12 Apr 2007 22:30:05 -0700 Subject: Define 'crlf' attribute. This defines the semantics of 'crlf' attribute as an example. When a path has this attribute unset (i.e. '!crlf'), autocrlf line-end conversion is not applied. Eventually we would want to let users to build a pipeline of processing to munge blob data to filesystem format (and in the other direction) based on combination of attributes, and at that point the mechanism in convert_to_{git,working_tree}() that looks at 'crlf' attribute needs to be enhanced. Perhaps the existing 'crlf' would become the first step in the input chain, and the last step in the output chain. Signed-off-by: Junio C Hamano --- t/t0020-crlf.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 't') diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 723b29ad1..600dcd30a 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -214,4 +214,28 @@ test_expect_success 'apply patch --index (autocrlf=true)' ' } ' +test_expect_success '.gitattributes says two is binary' ' + + echo "two !crlf" >.gitattributes && + rm -f tmp one dir/two && + git repo-config core.autocrlf true && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + echo "Huh?" + false + else + : happy + fi && + + if remove_cr one >/dev/null + then + : happy + else + echo "Huh?" + false + fi +' + test_done -- cgit v1.2.1 From e4aee10a2eaf0937d86d046f85ee569a75cae9ac Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sun, 15 Apr 2007 14:56:09 -0700 Subject: Change attribute negation marker from '!' to '-'. At the same time, we do not want to allow arbitrary strings for attribute names, as we are likely to want to extend the syntax later. Allow only alnum, dash, underscore and dot for now. Signed-off-by: Junio C Hamano --- t/t0020-crlf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 't') diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 600dcd30a..cf84f0a1a 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -216,7 +216,7 @@ test_expect_success 'apply patch --index (autocrlf=true)' ' test_expect_success '.gitattributes says two is binary' ' - echo "two !crlf" >.gitattributes && + echo "two -crlf" >.gitattributes && rm -f tmp one dir/two && git repo-config core.autocrlf true && git read-tree --reset -u HEAD && -- cgit v1.2.1 From 47579efc009c6f7afaf31be107eb92395a4f10db Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 17 Apr 2007 00:05:00 -0700 Subject: Add a demonstration/test of customized merge. This demonstrates how the new low-level per-path merge backends, union and ours, work, and shows how they are controlled by the gitattribute mechanism. Signed-off-by: Junio C Hamano --- t/t6026-merge-attr.sh | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 t/t6026-merge-attr.sh (limited to 't') diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh new file mode 100755 index 000000000..5daa2236d --- /dev/null +++ b/t/t6026-merge-attr.sh @@ -0,0 +1,72 @@ +#!/bin/sh +# +# Copyright (c) 2007 Junio C Hamano +# + +test_description='per path merge controlled by merge attribute' + +. ./test-lib.sh + +test_expect_success setup ' + + for f in text binary union + do + echo Initial >$f && git add $f || break + done && + test_tick && + git commit -m Initial && + + git branch side && + for f in text binary union + do + echo Master >>$f && git add $f || break + done && + test_tick && + git commit -m Master && + + git checkout side && + for f in text binary union + do + echo Side >>$f && git add $f || break + done && + test_tick && + git commit -m Side + +' + +test_expect_success merge ' + + { + echo "binary -merge" + echo "union merge=union" + } >.gitattributes && + + if git merge master + then + echo Gaah, should have conflicted + false + else + echo Ok, conflicted. + fi +' + +test_expect_success 'check merge result in index' ' + + git ls-files -u | grep binary && + git ls-files -u | grep text && + ! (git ls-files -u | grep union) + +' + +test_expect_success 'check merge result in working tree' ' + + git cat-file -p HEAD:binary >binary-orig && + grep "<<<<<<<" text && + cmp binary-orig binary && + ! grep "<<<<<<<" union && + grep Master union && + grep Side union + +' + +test_done -- cgit v1.2.1 From f3ef6b6bbe9bfd3d09130f7e26b87dbe11b93c5b Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 17 Apr 2007 22:51:45 -0700 Subject: Custom low-level merge driver support. This allows users to specify custom low-level merge driver per path, using the attributes mechanism. Just like you can specify one of built-in "text", "binary", "union" low-level merge drivers by saying: * merge=text .gitignore merge=union *.jpg merge=binary pick a name of your favorite merge driver, and assign it as the value of the 'merge' attribute. A custom low-level merge driver is defined via the config mechanism. This patch introduces 'merge.driver', a multi-valued configuration. Its value is the name (i.e. the one you use as the value of 'merge' attribute) followed by a command line specification. The command line can contain %O, %A, and %B to be interpolated with the names of temporary files that hold the common ancestor version, the version from your branch, and the version from the other branch, and the resulting command is spawned. The low-level merge driver is expected to update the temporary file for your branch (i.e. %A) with the result and exit with status 0 for a clean merge, and non-zero status for a conflicted merge. A new test in t6026 demonstrates a sample usage. Signed-off-by: Junio C Hamano --- t/t6026-merge-attr.sh | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 't') diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh index 5daa2236d..1732b60ed 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6026-merge-attr.sh @@ -30,8 +30,9 @@ test_expect_success setup ' echo Side >>$f && git add $f || break done && test_tick && - git commit -m Side + git commit -m Side && + git tag anchor ' test_expect_success merge ' @@ -69,4 +70,72 @@ test_expect_success 'check merge result in working tree' ' ' +cat >./custom-merge <<\EOF +#!/bin/sh + +orig="$1" ours="$2" theirs="$3" exit="$4" +( + echo "orig is $orig" + echo "ours is $ours" + echo "theirs is $theirs" + echo "=== orig ===" + cat "$orig" + echo "=== ours ===" + cat "$ours" + echo "=== theirs ===" + cat "$theirs" +) >"$ours+" +cat "$ours+" >"$ours" +rm -f "$ours+" +exit "$exit" +EOF +chmod +x ./custom-merge + +test_expect_success 'custom merge backend' ' + + echo "* merge=union" >.gitattributes && + echo "text merge=custom" >>.gitattributes && + + git reset --hard anchor && + git config --replace-all \ + merge.driver "custom ./custom-merge %O %A %B 0" && + + git merge master && + + cmp binary union && + sed -e 1,3d text >check-1 && + o=$(git-unpack-file master^:text) && + a=$(git-unpack-file side^:text) && + b=$(git-unpack-file master:text) && + sh -c "./custom-merge $o $a $b 0" && + sed -e 1,3d $a >check-2 && + cmp check-1 check-2 && + rm -f $o $a $b +' + +test_expect_success 'custom merge backend' ' + + git reset --hard anchor && + git config --replace-all \ + merge.driver "custom ./custom-merge %O %A %B 1" && + + if git merge master + then + echo "Eh? should have conflicted" + false + else + echo "Ok, conflicted" + fi && + + cmp binary union && + sed -e 1,3d text >check-1 && + o=$(git-unpack-file master^:text) && + a=$(git-unpack-file anchor:text) && + b=$(git-unpack-file master:text) && + sh -c "./custom-merge $o $a $b 0" && + sed -e 1,3d $a >check-2 && + cmp check-1 check-2 && + rm -f $o $a $b +' + test_done -- cgit v1.2.1 From 153920da5b62024c0aceef23252b82ad18e5fe22 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 18 Apr 2007 11:27:32 -0700 Subject: Custom low-level merge driver: change the configuration scheme. This changes the configuration syntax for defining a low-level merge driver to be: [merge "<>"] driver = "<>" name = "<>" which is much nicer to read and is extensible. Credit goes to Martin Waitz and Linus. In addition, when we use an external low-level merge driver, it is reported as an extra output from merge-recursive, using the value of merge.<.name variable. The demonstration in t6026 has also been updated. Signed-off-by: Junio C Hamano --- t/t6026-merge-attr.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 't') diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh index 1732b60ed..56fc34176 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6026-merge-attr.sh @@ -98,7 +98,9 @@ test_expect_success 'custom merge backend' ' git reset --hard anchor && git config --replace-all \ - merge.driver "custom ./custom-merge %O %A %B 0" && + merge.custom.driver "./custom-merge %O %A %B 0" && + git config --replace-all \ + merge.custom.name "custom merge driver for testing" && git merge master && @@ -117,7 +119,9 @@ test_expect_success 'custom merge backend' ' git reset --hard anchor && git config --replace-all \ - merge.driver "custom ./custom-merge %O %A %B 1" && + merge.custom.driver "./custom-merge %O %A %B 1" && + git config --replace-all \ + merge.custom.name "custom merge driver for testing" && if git merge master then -- cgit v1.2.1 From 163b95919428cd7d782af91296e0b886683f2daa Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Thu, 19 Apr 2007 22:37:19 -0700 Subject: Update 'crlf' attribute semantics. This updates the semantics of 'crlf' so that .gitattributes file can say "this is text, even though it may look funny". Setting the `crlf` attribute on a path is meant to mark the path as a "text" file. 'core.autocrlf' conversion takes place without guessing the content type by inspection. Unsetting the `crlf` attribute on a path is meant to mark the path as a "binary" file. The path never goes through line endings conversion upon checkin/checkout. Unspecified `crlf` attribute tells git to apply the `core.autocrlf` conversion when the file content looks like text. Setting the `crlf` attribut to string value "input" is similar to setting the attribute to `true`, but also forces git to act as if `core.autocrlf` is set to `input` for the path. Signed-off-by: Junio C Hamano --- t/t0020-crlf.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 11 deletions(-) (limited to 't') diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index cf84f0a1a..fe1dfd08a 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -4,6 +4,10 @@ test_description='CRLF conversion' . ./test-lib.sh +q_to_nul () { + tr Q '\0' +} + append_cr () { sed -e 's/$/Q/' | tr Q '\015' } @@ -20,6 +24,7 @@ test_expect_success setup ' for w in Hello world how are you; do echo $w; done >one && mkdir dir && for w in I am very very fine thank you; do echo $w; done >dir/two && + for w in Oh here is NULQin text here; do echo $w; done | q_to_nul >three && git add . && git commit -m initial && @@ -27,6 +32,7 @@ test_expect_success setup ' one=`git rev-parse HEAD:one` && dir=`git rev-parse HEAD:dir` && two=`git rev-parse HEAD:dir/two` && + three=`git rev-parse HEAD:three` && for w in Some extra lines here; do echo $w; done >>one && git diff >patch.file && @@ -38,7 +44,7 @@ test_expect_success setup ' test_expect_success 'update with autocrlf=input' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git read-tree --reset -u HEAD && git repo-config core.autocrlf input && @@ -62,7 +68,7 @@ test_expect_success 'update with autocrlf=input' ' test_expect_success 'update with autocrlf=true' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git read-tree --reset -u HEAD && git repo-config core.autocrlf true && @@ -86,7 +92,7 @@ test_expect_success 'update with autocrlf=true' ' test_expect_success 'checkout with autocrlf=true' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf true && git read-tree --reset -u HEAD && @@ -110,7 +116,7 @@ test_expect_success 'checkout with autocrlf=true' ' test_expect_success 'checkout with autocrlf=input' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf input && git read-tree --reset -u HEAD && @@ -136,7 +142,7 @@ test_expect_success 'checkout with autocrlf=input' ' test_expect_success 'apply patch (autocrlf=input)' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf input && git read-tree --reset -u HEAD && @@ -149,7 +155,7 @@ test_expect_success 'apply patch (autocrlf=input)' ' test_expect_success 'apply patch --cached (autocrlf=input)' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf input && git read-tree --reset -u HEAD && @@ -162,7 +168,7 @@ test_expect_success 'apply patch --cached (autocrlf=input)' ' test_expect_success 'apply patch --index (autocrlf=input)' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf input && git read-tree --reset -u HEAD && @@ -176,7 +182,7 @@ test_expect_success 'apply patch --index (autocrlf=input)' ' test_expect_success 'apply patch (autocrlf=true)' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf true && git read-tree --reset -u HEAD && @@ -189,7 +195,7 @@ test_expect_success 'apply patch (autocrlf=true)' ' test_expect_success 'apply patch --cached (autocrlf=true)' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf true && git read-tree --reset -u HEAD && @@ -202,7 +208,7 @@ test_expect_success 'apply patch --cached (autocrlf=true)' ' test_expect_success 'apply patch --index (autocrlf=true)' ' - rm -f tmp one dir/two && + rm -f tmp one dir/two three && git repo-config core.autocrlf true && git read-tree --reset -u HEAD && @@ -216,8 +222,8 @@ test_expect_success 'apply patch --index (autocrlf=true)' ' test_expect_success '.gitattributes says two is binary' ' + rm -f tmp one dir/two three && echo "two -crlf" >.gitattributes && - rm -f tmp one dir/two && git repo-config core.autocrlf true && git read-tree --reset -u HEAD && @@ -230,6 +236,52 @@ test_expect_success '.gitattributes says two is binary' ' fi && if remove_cr one >/dev/null + then + : happy + else + echo "Huh?" + false + fi && + + if remove_cr three >/dev/null + then + echo "Huh?" + false + else + : happy + fi +' + +test_expect_success '.gitattributes says two is input' ' + + rm -f tmp one dir/two three && + echo "two crlf=input" >.gitattributes && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + echo "Huh?" + false + else + : happy + fi +' + +test_expect_success '.gitattributes says two and three are text' ' + + rm -f tmp one dir/two three && + echo "t* crlf" >.gitattributes && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + : happy + else + echo "Huh?" + false + fi && + + if remove_cr three >/dev/null then : happy else -- cgit v1.2.1