Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/cvs-migration.txt3
-rw-r--r--Documentation/git-gc.txt15
-rw-r--r--builtin-remote.c1
-rw-r--r--cache-tree.c7
-rw-r--r--remote.c32
-rwxr-xr-xt/t0004-unwritable.sh67
-rwxr-xr-xt/t5505-remote.sh10
-rwxr-xr-xt/t5516-fetch-push.sh54
8 files changed, 170 insertions, 19 deletions
diff --git a/Documentation/cvs-migration.txt b/Documentation/cvs-migration.txt
index ea98900228..00f2e36b2e 100644
--- a/Documentation/cvs-migration.txt
+++ b/Documentation/cvs-migration.txt
@@ -8,7 +8,8 @@ designating a single shared repository which people can synchronize with;
this document explains how to do that.
Some basic familiarity with git is required. This
-link:tutorial.html[tutorial introduction to git] should be sufficient.
+link:tutorial.html[tutorial introduction to git] and the
+link:glossary.html[git glossary] should be sufficient.
Developing against a shared repository
--------------------------------------
diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt
index d424a4ecbe..b6b5ce1519 100644
--- a/Documentation/git-gc.txt
+++ b/Documentation/git-gc.txt
@@ -104,6 +104,21 @@ The optional configuration variable 'gc.pruneExpire' controls how old
the unreferenced loose objects have to be before they are pruned. The
default is "2 weeks ago".
+
+Notes
+-----
+
+git-gc tries very hard to be safe about the garbage it collects. In
+particular, it will keep not only objects referenced by your current set
+of branches and tags, but also objects referenced by the index, remote
+tracking branches, refs saved by linkgit:git-filter-branch[1] in
+refs/original/, or reflogs (which may references commits in branches
+that were later amended or rewound).
+
+If you are expecting some objects to be collected and they aren't, check
+all of those locations and decide whether it makes sense in your case to
+remove those references.
+
See Also
--------
linkgit:git-prune[1]
diff --git a/builtin-remote.c b/builtin-remote.c
index a3ee1ac393..93bb84e1d4 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -107,6 +107,7 @@ static int add(int argc, const char **argv)
struct path_list_item *item = track.items + i;
strbuf_reset(&buf2);
+ strbuf_addch(&buf2, '+');
if (mirror)
strbuf_addf(&buf2, "refs/%s:refs/%s",
item->path, item->path);
diff --git a/cache-tree.c b/cache-tree.c
index 39da54d1e5..73cb340707 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -341,8 +341,11 @@ static int update_one(struct cache_tree *it,
if (dryrun)
hash_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1);
- else
- write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1);
+ else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1)) {
+ strbuf_release(&buffer);
+ return -1;
+ }
+
strbuf_release(&buffer);
it->entry_count = i;
#if DEBUG
diff --git a/remote.c b/remote.c
index 06ad15627a..2d9af4023e 100644
--- a/remote.c
+++ b/remote.c
@@ -812,6 +812,26 @@ static struct ref *make_linked_ref(const char *name, struct ref ***tail)
return ret;
}
+static char *guess_ref(const char *name, struct ref *peer)
+{
+ struct strbuf buf = STRBUF_INIT;
+ unsigned char sha1[20];
+
+ const char *r = resolve_ref(peer->name, sha1, 1, NULL);
+ if (!r)
+ return NULL;
+
+ if (!prefixcmp(r, "refs/heads/"))
+ strbuf_addstr(&buf, "refs/heads/");
+ else if (!prefixcmp(r, "refs/tags/"))
+ strbuf_addstr(&buf, "refs/tags/");
+ else
+ return NULL;
+
+ strbuf_addstr(&buf, name);
+ return strbuf_detach(&buf, NULL);
+}
+
static int match_explicit(struct ref *src, struct ref *dst,
struct ref ***dst_tail,
struct refspec *rs,
@@ -820,6 +840,7 @@ static int match_explicit(struct ref *src, struct ref *dst,
struct ref *matched_src, *matched_dst;
const char *dst_value = rs->dst;
+ char *dst_guess;
if (rs->pattern)
return errs;
@@ -866,10 +887,15 @@ static int match_explicit(struct ref *src, struct ref *dst,
case 0:
if (!memcmp(dst_value, "refs/", 5))
matched_dst = make_linked_ref(dst_value, dst_tail);
+ else if((dst_guess = guess_ref(dst_value, matched_src)))
+ matched_dst = make_linked_ref(dst_guess, dst_tail);
else
- error("dst refspec %s does not match any "
- "existing ref on the remote and does "
- "not start with refs/.", dst_value);
+ error("unable to push to unqualified destination: %s\n"
+ "The destination refspec neither matches an "
+ "existing ref on the remote nor\n"
+ "begins with refs/, and we are unable to "
+ "guess a prefix based on the source ref.",
+ dst_value);
break;
default:
matched_dst = NULL;
diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh
new file mode 100755
index 0000000000..9255c63c08
--- /dev/null
+++ b/t/t0004-unwritable.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+test_description='detect unwritable repository and fail correctly'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ >file &&
+ git add file &&
+ git commit -m initial &&
+ echo >file &&
+ git add file
+
+'
+
+test_expect_success 'write-tree should notice unwritable repository' '
+
+ (
+ chmod a-w .git/objects
+ test_must_fail git write-tree
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_expect_success 'commit should notice unwritable repository' '
+
+ (
+ chmod a-w .git/objects
+ test_must_fail git commit -m second
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_expect_success 'update-index should notice unwritable repository' '
+
+ (
+ echo a >file &&
+ chmod a-w .git/objects
+ test_must_fail git update-index file
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_expect_success 'add should notice unwritable repository' '
+
+ (
+ echo b >file &&
+ chmod a-w .git/objects
+ test_must_fail git add file
+ )
+ status=$?
+ chmod 775 .git/objects
+ (exit $status)
+
+'
+
+test_done
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index af2d077792..48ff2d424d 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -77,6 +77,16 @@ test_expect_success 'add another remote' '
)
'
+test_expect_success 'remote forces tracking branches' '
+(
+ cd test &&
+ case `git config remote.second.fetch` in
+ +*) true ;;
+ *) false ;;
+ esac
+)
+'
+
test_expect_success 'remove remote' '
(
cd test &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 6d7e738548..0a757d5b9f 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -209,19 +209,7 @@ test_expect_success 'push with weak ambiguity (2)' '
'
-test_expect_success 'push with ambiguity (1)' '
-
- mk_test remotes/origin/master remotes/frotz/master &&
- if git push testrepo master:master
- then
- echo "Oops, should have failed"
- false
- else
- check_push_result $the_first_commit remotes/origin/master remotes/frotz/master
- fi
-'
-
-test_expect_success 'push with ambiguity (2)' '
+test_expect_success 'push with ambiguity' '
mk_test heads/frotz tags/frotz &&
if git push testrepo master:frotz
@@ -285,6 +273,37 @@ test_expect_success 'push with colon-less refspec (4)' '
'
+test_expect_success 'push head with non-existant, incomplete dest' '
+
+ mk_test &&
+ git push testrepo master:branch &&
+ check_push_result $the_commit heads/branch
+
+'
+
+test_expect_success 'push tag with non-existant, incomplete dest' '
+
+ mk_test &&
+ git tag -f v1.0 &&
+ git push testrepo v1.0:tag &&
+ check_push_result $the_commit tags/tag
+
+'
+
+test_expect_success 'push sha1 with non-existant, incomplete dest' '
+
+ mk_test &&
+ test_must_fail git push testrepo `git rev-parse master`:foo
+
+'
+
+test_expect_success 'push ref expression with non-existant, incomplete dest' '
+
+ mk_test &&
+ test_must_fail git push testrepo master^:branch
+
+'
+
test_expect_success 'push with HEAD' '
mk_test heads/master &&
@@ -323,6 +342,15 @@ test_expect_success 'push with +HEAD' '
'
+test_expect_success 'push HEAD with non-existant, incomplete dest' '
+
+ mk_test &&
+ git checkout master &&
+ git push testrepo HEAD:branch &&
+ check_push_result $the_commit heads/branch
+
+'
+
test_expect_success 'push with config remote.*.push = HEAD' '
mk_test heads/local &&