* [PATCH 0/8 v2] improve push's refspec handling @ 2007-10-27 16:49 Steffen Prohaska 2007-10-27 16:50 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Steffen Prohaska 0 siblings, 1 reply; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:49 UTC (permalink / raw) To: git This patch series improves the refspec handling in push. It is a replacement for the series in sp/push-refspec (666df53d6868bf56ca6c9ed0a927d612c67fe68c). The series addresses some issues that were recently discussed on the mailing list. - creating remote refs requires a more explicit command [1]. - the current branch can be pushed as "git push HEAD" [2]. - matching of refs use same rules as git rev-parse [3]. - annoying error messages when working with shared repos are supressed [4]. [1] http://marc.info/?l=git&m=119286893014690&w=2 [2] http://marc.info/?l=git&m=119089831513994&w=2 [3] http://marc.info/?l=git&m=119224567631084&w=2 [4] http://marc.info/?t=119305127000001&r=1&w=2 Note, existing setups may break. Therefore, we need to decide if this series can be applied before git 1.6. All tests pass. Steffen Documentation/git-http-push.txt | 6 ++ Documentation/git-push.txt | 8 ++- Documentation/git-send-pack.txt | 18 ++++- builtin-push.c | 6 ++- builtin-rev-parse.c | 27 +++++--- cache.h | 2 + http-push.c | 9 ++- remote.c | 41 ++++++++---- remote.h | 2 +- send-pack.c | 70 ++++++++++++++++----- sha1_name.c | 52 +++++++++++++---- t/t5516-fetch-push.sh | 127 ++++++++++++++++++++++++++++++++++++++- transport.c | 8 ++- transport.h | 1 + 14 files changed, 311 insertions(+), 66 deletions(-) [PATCH 1/8] push: change push to fail if short ref name does not exist [PATCH 2/8] push: teach push new flag --create these two should be kept together. [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name This one is a bit off-topic and could be skipped. [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref ^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH 1/8] push: change push to fail if short ref name does not exist 2007-10-27 16:49 [PATCH 0/8 v2] improve push's refspec handling Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 2/8] push: teach push new flag --create Steffen Prohaska ` (2 more replies) 0 siblings, 3 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska You can use a branch's shortname to push it. Push used to create the branch on the remote side if it did not yet exist. If you specified the wrong branch accidentally it was created. A safety valve that pushes only existing branches may help to avoid errors. This commit changes push to fail if the remote ref does not yet exist and the refspec does not start with refs/. Remote refs must explicitly be created with their full name. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- remote.c | 5 +++-- t/t5516-fetch-push.sh | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/remote.c b/remote.c index 170015a..ec992c9 100644 --- a/remote.c +++ b/remote.c @@ -611,6 +611,7 @@ static int match_explicit(struct ref *src, struct ref *dst, struct ref *matched_src, *matched_dst; const char *dst_value = rs->dst; + const char * const orig_dst_value = rs->dst ? rs->dst : rs->src; if (rs->pattern) return errs; @@ -647,12 +648,12 @@ static int match_explicit(struct ref *src, struct ref *dst, case 1: break; case 0: - if (!memcmp(dst_value, "refs/", 5)) + if (!memcmp(orig_dst_value , "refs/", 5)) matched_dst = make_linked_ref(dst_value, dst_tail); else error("dst refspec %s does not match any " "existing ref on the remote and does " - "not start with refs/.", dst_value); + "not start with refs/.", orig_dst_value); break; default: matched_dst = NULL; diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 4fbd5b1..5ba09e2 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -126,6 +126,36 @@ test_expect_success 'push with wildcard' ' ) ' +test_expect_success 'push nonexisting (1)' ' + + mk_test && + if git push testrepo master + then + echo "Oops, should have failed" + false + fi + +' + +test_expect_success 'push nonexisting (2)' ' + + mk_test && + if git push testrepo heads/master + then + echo "Oops, should have failed" + false + fi + +' + +test_expect_success 'push nonexisting (3)' ' + + mk_test && + git push testrepo refs/heads/master && + check_push_result $the_commit heads/master + +' + test_expect_success 'push with matching heads' ' mk_test heads/master && @@ -225,7 +255,7 @@ test_expect_success 'push with colon-less refspec (3)' ' git tag -d frotz fi && git branch -f frotz master && - git push testrepo frotz && + git push testrepo refs/heads/frotz && check_push_result $the_commit heads/frotz && test 1 = $( cd testrepo && git show-ref | wc -l ) ' @@ -238,7 +268,7 @@ test_expect_success 'push with colon-less refspec (4)' ' git branch -D frotz fi && git tag -f frotz && - git push testrepo frotz && + git push testrepo refs/tags/frotz && check_push_result $the_commit tags/frotz && test 1 = $( cd testrepo && git show-ref | wc -l ) -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 2/8] push: teach push new flag --create 2007-10-27 16:50 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Steffen Prohaska 2007-10-27 21:42 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 1 reply; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska Refs that do not start with 'refs/' will only be created at the remote if --create is used. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- Documentation/git-http-push.txt | 6 ++++++ Documentation/git-push.txt | 8 +++++++- Documentation/git-send-pack.txt | 14 +++++++++++--- builtin-push.c | 6 +++++- http-push.c | 9 +++++++-- remote.c | 18 +++++++++++++----- remote.h | 2 +- send-pack.c | 9 +++++++-- t/t5516-fetch-push.sh | 8 ++++++++ transport.c | 8 ++++++-- transport.h | 1 + 11 files changed, 72 insertions(+), 17 deletions(-) diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.txt index 3a69b71..8753611 100644 --- a/Documentation/git-http-push.txt +++ b/Documentation/git-http-push.txt @@ -30,6 +30,12 @@ OPTIONS the remote repository can lose commits; use it with care. +\--create:: + Usually, the command refuses to create a remote ref that is + not specified by its full name, i.e. starting with 'refs/'. + This flag tells the command to create the remote ref under + the full name of the local matching ref. + --dry-run:: Do everything except actually send the updates. diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index e5dd4c1..67b354b 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects SYNOPSIS -------- [verse] -'git-push' [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] +'git-push' [--all] [--dry-run] [--create] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...] DESCRIPTION @@ -86,6 +86,12 @@ the remote repository. This flag disables the check. This can cause the remote repository to lose commits; use it with care. +\--create:: + Usually, the command refuses to create a remote ref that is + not specified by its full name, i.e. starting with 'refs/'. + This flag tells the command to create the remote ref under + the full name of the local matching ref. + \--repo=<repo>:: When no repository is specified the command defaults to "origin"; this overrides it. diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt index 2fa01d4..01495df 100644 --- a/Documentation/git-send-pack.txt +++ b/Documentation/git-send-pack.txt @@ -44,6 +44,12 @@ OPTIONS the remote repository can lose commits; use it with care. +\--create:: + Usually, the command refuses to create a remote ref that is + not specified by its full name, i.e. starting with 'refs/'. + This flag tells the command to create the remote ref under + the full name of the local matching ref. + \--verbose:: Run verbosely. @@ -97,9 +103,11 @@ destination side. * it has to start with "refs/"; <dst> is used as the destination literally in this case. - * <src> == <dst> and the ref that matched the <src> must not - exist in the set of remote refs; the ref matched <src> - locally is used as the name of the destination. + * Only <src> is specified and the ref that matched + <src> must not exist in the set of remote refs; + and the '--create' flag is used; + the ref matched <src> locally is used as the name of + the destination. Without '--force', the <src> ref is stored at the remote only if <dst> does not exist, or <dst> is a proper subset (i.e. an diff --git a/builtin-push.c b/builtin-push.c index 4b39ef3..4ab1401 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -8,7 +8,7 @@ #include "remote.h" #include "transport.h" -static const char push_usage[] = "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]"; +static const char push_usage[] = "git-push [--all] [--dry-run] [--create] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]"; static int thin, verbose; static const char *receivepack; @@ -113,6 +113,10 @@ int cmd_push(int argc, const char **argv, const char *prefix) flags |= TRANSPORT_PUSH_DRY_RUN; continue; } + if (!strcmp(arg, "--create")) { + flags |= TRANSPORT_PUSH_CREATE; + continue; + } if (!strcmp(arg, "--tags")) { add_refspec("refs/tags/*"); continue; diff --git a/http-push.c b/http-push.c index c02a3af..4ad9f26 100644 --- a/http-push.c +++ b/http-push.c @@ -13,7 +13,7 @@ #include <expat.h> static const char http_push_usage[] = -"git-http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...]\n"; +"git-http-push [--all] [--dry-run] [--create] [--force] [--verbose] <remote> [<head>...]\n"; #ifndef XML_STATUS_OK enum XML_Status { @@ -81,6 +81,7 @@ static int push_verbosely; static int push_all; static int force_all; static int dry_run; +static int create; static struct object_list *objects; @@ -2307,6 +2308,10 @@ int main(int argc, char **argv) dry_run = 1; continue; } + if (!strcmp(arg, "--create")) { + create = 1; + continue; + } if (!strcmp(arg, "--verbose")) { push_verbosely = 1; continue; @@ -2389,7 +2394,7 @@ int main(int argc, char **argv) if (!remote_tail) remote_tail = &remote_refs; if (match_refs(local_refs, remote_refs, &remote_tail, - nr_refspec, refspec, push_all)) + nr_refspec, refspec, push_all, create)) return -1; if (!remote_refs) { fprintf(stderr, "No refs in common and none specified; doing nothing.\n"); diff --git a/remote.c b/remote.c index ec992c9..8908a19 100644 --- a/remote.c +++ b/remote.c @@ -606,7 +606,7 @@ static struct ref *make_linked_ref(const char *name, struct ref ***tail) static int match_explicit(struct ref *src, struct ref *dst, struct ref ***dst_tail, struct refspec *rs, - int errs) + int errs, int create) { struct ref *matched_src, *matched_dst; @@ -650,6 +650,14 @@ static int match_explicit(struct ref *src, struct ref *dst, case 0: if (!memcmp(orig_dst_value , "refs/", 5)) matched_dst = make_linked_ref(dst_value, dst_tail); + else if (!memcmp(dst_value, "refs/", 5)) + if (create) + matched_dst = make_linked_ref(dst_value, dst_tail); + else + error("dst refspec %s does not match any " + "existing ref on the remote. " + "If you want to create is use --create.", + orig_dst_value); else error("dst refspec %s does not match any " "existing ref on the remote and does " @@ -677,11 +685,11 @@ static int match_explicit(struct ref *src, struct ref *dst, static int match_explicit_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, struct refspec *rs, - int rs_nr) + int rs_nr, int create) { int i, errs; for (i = errs = 0; i < rs_nr; i++) - errs |= match_explicit(src, dst, dst_tail, &rs[i], errs); + errs |= match_explicit(src, dst, dst_tail, &rs[i], errs, create); return -errs; } @@ -711,12 +719,12 @@ static const struct refspec *check_pattern_match(const struct refspec *rs, * without thinking. */ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, - int nr_refspec, char **refspec, int all) + int nr_refspec, char **refspec, int all, int create) { struct refspec *rs = parse_ref_spec(nr_refspec, (const char **) refspec); - if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec)) + if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec, create)) return -1; /* pick the remainder */ diff --git a/remote.h b/remote.h index c62636d..7d731b1 100644 --- a/remote.h +++ b/remote.h @@ -57,7 +57,7 @@ void ref_remove_duplicates(struct ref *ref_map); struct refspec *parse_ref_spec(int nr_refspec, const char **refspec); int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail, - int nr_refspec, char **refspec, int all); + int nr_refspec, char **refspec, int all, int create); /* * Given a list of the remote refs and the specification of things to diff --git a/send-pack.c b/send-pack.c index e9b9a39..77acae1 100644 --- a/send-pack.c +++ b/send-pack.c @@ -7,7 +7,7 @@ #include "remote.h" static const char send_pack_usage[] = -"git-send-pack [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n" +"git-send-pack [--all] [--dry-run] [--create] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n" " --all and explicit <ref> specification are mutually exclusive."; static const char *receivepack = "git-receive-pack"; static int verbose; @@ -15,6 +15,7 @@ static int send_all; static int force_update; static int use_thin_pack; static int dry_run; +static int create; /* * Make a pack stream and spit it out into file descriptor fd @@ -201,7 +202,7 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha if (!remote_tail) remote_tail = &remote_refs; if (match_refs(local_refs, remote_refs, &remote_tail, - nr_refspec, refspec, send_all)) + nr_refspec, refspec, send_all, create)) return -1; if (!remote_refs) { @@ -398,6 +399,10 @@ int main(int argc, char **argv) dry_run = 1; continue; } + if (!strcmp(arg, "--create")) { + create = 1; + continue; + } if (!strcmp(arg, "--force")) { force_update = 1; continue; diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 5ba09e2..42ca0ff 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -156,6 +156,14 @@ test_expect_success 'push nonexisting (3)' ' ' +test_expect_success 'push nonexisting (4)' ' + + mk_test && + git push testrepo --create master && + check_push_result $the_commit heads/master + +' + test_expect_success 'push with matching heads' ' mk_test heads/master && diff --git a/transport.c b/transport.c index 400af71..fbdbd0d 100644 --- a/transport.c +++ b/transport.c @@ -385,7 +385,7 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons int argc; int err; - argv = xmalloc((refspec_nr + 11) * sizeof(char *)); + argv = xmalloc((refspec_nr + 12) * sizeof(char *)); argv[0] = "http-push"; argc = 1; if (flags & TRANSPORT_PUSH_ALL) @@ -394,6 +394,8 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons argv[argc++] = "--force"; if (flags & TRANSPORT_PUSH_DRY_RUN) argv[argc++] = "--dry-run"; + if (flags & TRANSPORT_PUSH_CREATE) + argv[argc++] = "--create"; argv[argc++] = transport->url; while (refspec_nr--) argv[argc++] = *refspec++; @@ -658,7 +660,7 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const int argc; int err; - argv = xmalloc((refspec_nr + 11) * sizeof(char *)); + argv = xmalloc((refspec_nr + 12) * sizeof(char *)); argv[0] = "send-pack"; argc = 1; if (flags & TRANSPORT_PUSH_ALL) @@ -667,6 +669,8 @@ static int git_transport_push(struct transport *transport, int refspec_nr, const argv[argc++] = "--force"; if (flags & TRANSPORT_PUSH_DRY_RUN) argv[argc++] = "--dry-run"; + if (flags & TRANSPORT_PUSH_CREATE) + argv[argc++] = "--create"; if (data->receivepack) { char *rp = xmalloc(strlen(data->receivepack) + 16); sprintf(rp, "--receive-pack=%s", data->receivepack); diff --git a/transport.h b/transport.h index df12ea7..1d6a926 100644 --- a/transport.h +++ b/transport.h @@ -30,6 +30,7 @@ struct transport { #define TRANSPORT_PUSH_ALL 1 #define TRANSPORT_PUSH_FORCE 2 #define TRANSPORT_PUSH_DRY_RUN 4 +#define TRANSPORT_PUSH_CREATE 8 /* Returns a transport suitable for the url */ struct transport *transport_get(struct remote *, const char *); -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand 2007-10-27 16:50 ` [PATCH 2/8] push: teach push new flag --create Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name Steffen Prohaska 2007-10-28 7:28 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Junio C Hamano 0 siblings, 2 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska Deep inside get_sha1() the name of the requested ref is matched according to the rules documented in git-rev-parse. This patch introduces a function that returns the full name of the matched ref to the outside. For example 'master' is typically returned as 'refs/heads/master'. The new function can be used by "git rev-parse" to print the full name of the matched ref and can be used by "git send-pack" to expand a local ref to its full name. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- cache.h | 1 + sha1_name.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/cache.h b/cache.h index 27485d3..726948b 100644 --- a/cache.h +++ b/cache.h @@ -401,6 +401,7 @@ static inline unsigned int hexval(unsigned char c) extern int get_sha1(const char *str, unsigned char *sha1); extern int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode); +extern int get_sha1_with_real_ref(const char *str, unsigned char *sha1, char **real_ref); extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ extern int read_ref(const char *filename, unsigned char *sha1); diff --git a/sha1_name.c b/sha1_name.c index 2d727d5..b820909 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -306,7 +306,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log) return logs_found; } -static int get_sha1_basic(const char *str, int len, unsigned char *sha1) +static int get_sha1_basic(const char *str, int len, unsigned char *sha1, char **real_ref_out) { static const char *warning = "warning: refname '%.*s' is ambiguous.\n"; char *real_ref = NULL; @@ -378,17 +378,21 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) } } - free(real_ref); + if (real_ref_out) { + *real_ref_out = real_ref; + } else { + free(real_ref); + } return 0; } -static int get_sha1_1(const char *name, int len, unsigned char *sha1); +static int get_sha1_1(const char *name, int len, unsigned char *sha1, char **real_ref); static int get_parent(const char *name, int len, unsigned char *result, int idx) { unsigned char sha1[20]; - int ret = get_sha1_1(name, len, sha1); + int ret = get_sha1_1(name, len, sha1, /*real_ref=*/ 0); struct commit *commit; struct commit_list *p; @@ -418,7 +422,7 @@ static int get_nth_ancestor(const char *name, int len, unsigned char *result, int generation) { unsigned char sha1[20]; - int ret = get_sha1_1(name, len, sha1); + int ret = get_sha1_1(name, len, sha1, /*real_ref=*/ 0); if (ret) return ret; @@ -471,7 +475,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) else return -1; - if (get_sha1_1(name, sp - name - 2, outer)) + if (get_sha1_1(name, sp - name - 2, outer, /*real_ref=*/ 0)) return -1; o = parse_object(outer); @@ -531,7 +535,7 @@ static int get_describe_name(const char *name, int len, unsigned char *sha1) return -1; } -static int get_sha1_1(const char *name, int len, unsigned char *sha1) +static int get_sha1_1(const char *name, int len, unsigned char *sha1, char **real_ref) { int ret, has_suffix; const char *cp; @@ -569,7 +573,7 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1) if (!ret) return 0; - ret = get_sha1_basic(name, len, sha1); + ret = get_sha1_basic(name, len, sha1, real_ref); if (!ret) return 0; @@ -651,14 +655,14 @@ int get_sha1(const char *name, unsigned char *sha1) return get_sha1_with_mode(name, sha1, &unused); } -int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode) +int get_sha1_with_mode_real_ref(const char *name, unsigned char *sha1, unsigned *mode, char** real_ref) { int ret, bracket_depth; int namelen = strlen(name); const char *cp; *mode = S_IFINVALID; - ret = get_sha1_1(name, namelen, sha1); + ret = get_sha1_1(name, namelen, sha1, real_ref); if (!ret) return ret; /* sha1:path --> object name of path in ent sha1 @@ -709,9 +713,21 @@ int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode) } if (*cp == ':') { unsigned char tree_sha1[20]; - if (!get_sha1_1(name, cp-name, tree_sha1)) + if (!get_sha1_1(name, cp-name, tree_sha1, real_ref)) return get_tree_entry(tree_sha1, cp+1, sha1, mode); } return ret; } + +int get_sha1_with_mode(const char *name, unsigned char *sha1, unsigned *mode) +{ + return get_sha1_with_mode_real_ref(name, sha1, mode, 0); +} + +int get_sha1_with_real_ref(const char *name, unsigned char *sha1, char **real_ref) +{ + unsigned unused; + return get_sha1_with_mode_real_ref(name, sha1, &unused, real_ref); +} + -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-27 16:50 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska ` (2 more replies) 2007-10-28 7:28 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Junio C Hamano 1 sibling, 3 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska "git rev-parse --symbolic" used to return the ref name as it was specified on the command line. This is changed to returning the full matched ref name, i.e. "git rev-parse --symbolic master" now typically returns "refs/heads/master". Note, this changes output of an established command. It might break existing setups. I checked that it does not break scripts in git.git. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- builtin-rev-parse.c | 27 +++++++++++++++++---------- 1 files changed, 17 insertions(+), 10 deletions(-) diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index 8d78b69..e64abeb 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -93,7 +93,7 @@ static void show(const char *arg) } /* Output a revision, only if filter allows it */ -static void show_rev(int type, const unsigned char *sha1, const char *name) +static void show_rev(int type, const unsigned char *sha1, const char *name, const char* real_name) { if (!(filter & DO_REVS)) return; @@ -102,7 +102,9 @@ static void show_rev(int type, const unsigned char *sha1, const char *name) if (type != show_type) putchar('^'); - if (symbolic && name) + if (symbolic && real_name) + show(real_name); + else if (symbolic && name) show(name); else if (abbrev) show(find_unique_abbrev(sha1, abbrev)); @@ -131,7 +133,7 @@ static void show_default(void) def = NULL; if (!get_sha1(s, sha1)) { - show_rev(NORMAL, sha1, s); + show_rev(NORMAL, sha1, s, 0); return; } } @@ -139,7 +141,7 @@ static void show_default(void) static int show_reference(const char *refname, const unsigned char *sha1, int flag, void *cb_data) { - show_rev(NORMAL, sha1, refname); + show_rev(NORMAL, sha1, refname, 0); return 0; } @@ -187,8 +189,8 @@ static int try_difference(const char *arg) if (dotdot == arg) this = "HEAD"; if (!get_sha1(this, sha1) && !get_sha1(next, end)) { - show_rev(NORMAL, end, next); - show_rev(symmetric ? NORMAL : REVERSED, sha1, this); + show_rev(NORMAL, end, next, 0); + show_rev(symmetric ? NORMAL : REVERSED, sha1, this, 0); if (symmetric) { struct commit_list *exclude; struct commit *a, *b; @@ -198,7 +200,7 @@ static int try_difference(const char *arg) while (exclude) { struct commit_list *n = exclude->next; show_rev(REVERSED, - exclude->item->object.sha1,NULL); + exclude->item->object.sha1, NULL, 0); free(exclude); exclude = n; } @@ -213,6 +215,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) { int i, as_is = 0, verify = 0; unsigned char sha1[20]; + char* real_name = 0; git_config(git_default_config); @@ -393,12 +396,16 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) /* Not a flag argument */ if (try_difference(arg)) continue; - if (!get_sha1(arg, sha1)) { - show_rev(NORMAL, sha1, arg); + if (!get_sha1_with_real_ref(arg, sha1, &real_name)) { + show_rev(NORMAL, sha1, arg, real_name); + if(real_name) { + free(real_name); + real_name = 0; + } continue; } if (*arg == '^' && !get_sha1(arg+1, sha1)) { - show_rev(REVERSED, sha1, arg+1); + show_rev(REVERSED, sha1, arg+1, 0); continue; } as_is = 1; -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-27 16:50 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska ` (2 more replies) 2007-10-27 21:53 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full " Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 3 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska This teaches "push <remote> HEAD" to resolve HEAD on the local side to its real ref name, e.g. refs/heads/master, and then use the real ref name on the remote side to search a matching remote ref. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- remote.c | 13 ++++++++++--- t/t5516-fetch-push.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/remote.c b/remote.c index 8908a19..1c96659 100644 --- a/remote.c +++ b/remote.c @@ -575,6 +575,8 @@ static struct ref *try_explicit_object_name(const char *name) unsigned char sha1[20]; struct ref *ref; int len; + char *real_name = 0; + const char *best_name; if (!*name) { ref = alloc_ref(20); @@ -582,12 +584,17 @@ static struct ref *try_explicit_object_name(const char *name) hashclr(ref->new_sha1); return ref; } - if (get_sha1(name, sha1)) + if (get_sha1_with_real_ref(name, sha1, &real_name)) return NULL; - len = strlen(name) + 1; + best_name = real_name ? real_name : name; + len = strlen(best_name) + 1; ref = alloc_ref(len); - memcpy(ref->name, name, len); + memcpy(ref->name, best_name, len); hashcpy(ref->new_sha1, sha1); + + if (real_name) { + free(real_name); + } return ref; } diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 42ca0ff..0ff791a 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -282,6 +282,35 @@ test_expect_success 'push with colon-less refspec (4)' ' ' +test_expect_success 'push with HEAD' ' + + mk_test heads/master && + git push testrepo HEAD && + check_push_result $the_commit heads/master + +' + +test_expect_success 'push with HEAD (--create)' ' + + mk_test && + git push --create testrepo HEAD && + check_push_result $the_commit heads/master + +' + +test_expect_success 'push with HEAD nonexisting at remote' ' + + mk_test heads/master && + git checkout -b local master && + if git push testrepo HEAD + then + echo "Oops, should have failed" + false + else + check_push_result $the_first_commit heads/master + fi +' + test_expect_success 'push with dry-run' ' mk_test heads/master && -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Steffen Prohaska ` (2 more replies) 2007-10-27 22:03 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 3 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska ref_cmp_full_short(full_name, short_name) expands short_name according to the rules documented in git-rev-parse and compares the expanded name with full_name. It reports a match by returning 0. This function makes the rules for resolving refs to sha1s available for string comparison. Before this change, the rules were buried in get_sha1*() and dwim_ref(). ref_cmp_full_short() will be used for matching refspecs in git-send-pack. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- cache.h | 1 + sha1_name.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 0 deletions(-) diff --git a/cache.h b/cache.h index 726948b..e1385ac 100644 --- a/cache.h +++ b/cache.h @@ -406,6 +406,7 @@ extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ extern int read_ref(const char *filename, unsigned char *sha1); extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int *); +extern int ref_cmp_full_short(const char *full_name, const char *short_name); extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref); extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref); diff --git a/sha1_name.c b/sha1_name.c index b820909..2a1e093 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -249,6 +249,20 @@ static const char *ref_fmt[] = { NULL }; +int ref_cmp_full_short(const char *full_name, const char *short_name) +{ + const char **p; + const int short_name_len = strlen(short_name); + + for (p = ref_fmt; *p; p++) { + if (strcmp(full_name, mkpath(*p, short_name_len, short_name)) == 0) { + return 0; + } + } + + return -1; +} + int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) { const char **p, *r; -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-27 16:50 ` [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref Steffen Prohaska 2007-10-28 7:28 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Junio C Hamano 2007-10-27 22:16 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 2 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska This commit changes the rules for resolving refspecs to match the rules for resolving refs in rev-parse. git-rev-parse uses clear rules to resolve a short ref to its full name, which are well documented. The rules for resolving refspecs documented in git-send-pack were less strict and harder to understand. This commit replaces them by the rules of git-rev-parse. The unified rules are easier to understand and better resolve ambiguous cases. You can now push from a repository containing several branches ending on the same short name. Note, this breaks existing setups. For example "master" will no longer resolve to "origin/master". Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- Documentation/git-send-pack.txt | 4 +++- remote.c | 5 +---- t/t5516-fetch-push.sh | 12 +++++++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt index 01495df..08bcc25 100644 --- a/Documentation/git-send-pack.txt +++ b/Documentation/git-send-pack.txt @@ -91,7 +91,9 @@ Each pattern pair consists of the source side (before the colon) and the destination side (after the colon). The ref to be pushed is determined by finding a match that matches the source side, and where it is pushed is determined by using the -destination side. +destination side. The rules used to match a ref are the same +rules used by gitlink:git-rev-parse[1] to resolve a symbolic ref +name. - It is an error if <src> does not match exactly one of the local refs. diff --git a/remote.c b/remote.c index 1c96659..176457c 100644 --- a/remote.c +++ b/remote.c @@ -519,10 +519,7 @@ static int count_refspec_match(const char *pattern, char *name = refs->name; int namelen = strlen(name); - if (namelen < patlen || - memcmp(name + namelen - patlen, pattern, patlen)) - continue; - if (namelen != patlen && name[namelen - patlen - 1] != '/') + if (ref_cmp_full_short(name, pattern)) continue; /* A match is "weak" if it is with refs outside diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 0ff791a..9ec8216 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -183,11 +183,21 @@ test_expect_success 'push with no ambiguity (1)' ' test_expect_success 'push with no ambiguity (2)' ' mk_test remotes/origin/master && - git push testrepo master:master && + git push testrepo master:origin/master && check_push_result $the_commit remotes/origin/master ' +test_expect_success 'push with colon-less refspec, no ambiguity' ' + + mk_test heads/master heads/t/master && + git branch -f t/master master && + git push testrepo master && + check_push_result $the_commit heads/master && + check_push_result $the_first_commit heads/t/master + +' + test_expect_success 'push with weak ambiguity (1)' ' mk_test heads/master remotes/origin/master && -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref 2007-10-27 16:50 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Steffen Prohaska @ 2007-10-27 16:50 ` Steffen Prohaska 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 7:28 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Junio C Hamano 1 sibling, 1 reply; 36+ messages in thread From: Steffen Prohaska @ 2007-10-27 16:50 UTC (permalink / raw) To: git; +Cc: Steffen Prohaska git push reports errors if a remote ref is not a strict subset of a local ref. The push wouldn't be a fast-forward and is therefore refused. This is in general a good idea. But these messages can be annoying if you work with a shared remote repository. Branches at the remote may have advanced and you haven't pulled to all of your local branches. In this situation, local branches may be strict subsets of the remote heads. Pushing such branches wouldn't add any information to the remote. It would only reset the remote to an ancestor. A merge between the remote and the local branch is not very interested either because it would just be a fast forward of the local branch. In these cases you're not interested in the error message. This commit teaches git push to be quiet if the local is a strict subset of the remote and no refspec is explicitly specified on the command line. If the --verbose flag is used a "note:" is printed for each ignored branch. Signed-off-by: Steffen Prohaska <prohaska@zib.de> --- send-pack.c | 61 +++++++++++++++++++++++++++++++++++++------------ t/t5516-fetch-push.sh | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 15 deletions(-) diff --git a/send-pack.c b/send-pack.c index 77acae1..b95bed9 100644 --- a/send-pack.c +++ b/send-pack.c @@ -259,24 +259,55 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha !will_delete_ref && !is_null_sha1(ref->old_sha1) && !ref->force) { - if (!has_sha1_file(ref->old_sha1) || - !ref_newer(ref->peer_ref->new_sha1, - ref->old_sha1)) { - /* We do not have the remote ref, or - * we know that the remote ref is not - * an ancestor of what we are trying to - * push. Either way this can be losing - * commits at the remote end and likely - * we were not up to date to begin with. + if (!has_sha1_file(ref->old_sha1)) { + /* We do not have the remote ref. + * This can be losing commits at + * the remote end. */ - error("remote '%s' is not a strict " - "subset of local ref '%s'. " - "maybe you are not up-to-date and " - "need to pull first?", - ref->name, - ref->peer_ref->name); + error("You don't have the commit" + "for the remote ref '%s'." + "This may cause losing commits" + "that cannot be recovered.", + ref->name); ret = -2; continue; + } else if (!ref_newer(ref->peer_ref->new_sha1, + ref->old_sha1)) { + /* We know that the remote ref is not + * an ancestor of what we are trying to + * push. This can be losing commits at + * the remote end and likely we were not + * up to date to begin with. + * + * Therefore, we don't push. + * + * If no explicit refspec was passed on the + * commandline, then we only report an error + * if the local is not a strict subset of the + * remote. If the local is a strict subset we + * don't have new commits for the remote. + * Pulling and pushing wouldn't add anything to + * the remote. + * + */ + if (nr_refspec || + !ref_newer(ref->old_sha1, ref->peer_ref->new_sha1)) { + error("remote '%s' is not a strict " + "subset of local ref '%s'. " + "maybe you are not up-to-date and " + "need to pull first?", + ref->name, + ref->peer_ref->name); + ret = -2; + } else if (verbose) { + fprintf(stderr, + "note: ignoring local ref '%s' " + "because it is a strict " + "subset of remote '%s'.\n", + ref->peer_ref->name, + ref->name); + } + continue; } } hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9ec8216..c8493f9 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -331,4 +331,48 @@ test_expect_success 'push with dry-run' ' check_push_result $old_commit heads/master ' +test_expect_success 'push with local is strict subset (must not report error)' ' + + mk_test heads/foo && + git push testrepo $the_commit:refs/heads/foo && + git branch -f foo $old_commit && + if git push testrepo 2>&1 | grep ^error + then + echo "Oops, should not report error" + false + fi + +' + +test_expect_success 'push with explicit refname, local is strict subset (must report error)' ' + + mk_test heads/foo && + git push testrepo $the_commit:refs/heads/foo && + git branch -f foo $old_commit && + if ! git push testrepo foo 2>&1 | grep ^error + then + echo "Oops, should have reported error" + false + fi + +' + +test_expect_success 'push with neither local nor remote is strict subset (must report error)' ' + + mk_test heads/foo && + git push testrepo $the_commit:refs/heads/foo && + git branch -f foo $old_commit && + git checkout foo && + : >path3 && + git add path3 && + test_tick && + git commit -a -m branched && + if ! git push testrepo 2>&1 | grep ^error + then + echo "Oops, should have reported error" + false + fi + +' + test_done -- 1.5.3.4.1261.g626eb ^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref 2007-10-27 16:50 ` [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref Steffen Prohaska @ 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:20 ` Steffen Prohaska 0 siblings, 1 reply; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > git push reports errors if a remote ref is not a strict subset > of a local ref. The push wouldn't be a fast-forward and is > therefore refused. This is in general a good idea. > This commit teaches git push to be quiet if the local is a strict > subset of the remote and no refspec is explicitly specified on > the command line. If the --verbose flag is used a "note:" is > printed for each ignored branch. What happens to the summary reporting after such a push? Does it say "branch foo was not pushed because you did not touch it since you fetched and it is already stale with respect to the remote side which has updates since then"? How does this interact with the "pretend we have fetched immediately after we pushed by updating the corresponding remote tracking branch" logic? ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref 2007-10-28 7:28 ` Junio C Hamano @ 2007-10-28 8:20 ` Steffen Prohaska 0 siblings, 0 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 8:20 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> git push reports errors if a remote ref is not a strict subset >> of a local ref. The push wouldn't be a fast-forward and is >> therefore refused. This is in general a good idea. > >> This commit teaches git push to be quiet if the local is a strict >> subset of the remote and no refspec is explicitly specified on >> the command line. If the --verbose flag is used a "note:" is >> printed for each ignored branch. > > What happens to the summary reporting after such a push? Does > it say "branch foo was not pushed because you did not touch it > since you fetched and it is already stale with respect to the > remote side which has updates since then"? It says nothing, it's quiet, as promised in the commit message ;) That's the point of this patch. But I see your point. Maybe it should say something like "ignored 2 branches, which are strict subsets of remote." "use --verbose for details." ? > How does this interact with the "pretend we have fetched > immediately after we pushed by updating the corresponding remote > tracking branch" logic? I doesn't change a remote tracking branch. I'll add a test confirming this. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs 2007-10-27 16:50 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Steffen Prohaska 2007-10-27 16:50 ` [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref Steffen Prohaska @ 2007-10-28 7:28 ` Junio C Hamano 1 sibling, 0 replies; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > This commit changes the rules for resolving refspecs to match the > rules for resolving refs in rev-parse. git-rev-parse uses clear rules > to resolve a short ref to its full name, which are well documented. > The rules for resolving refspecs documented in git-send-pack were > less strict and harder to understand. This commit replaces them by > the rules of git-rev-parse. > > The unified rules are easier to understand and better resolve ambiguous > cases. You can now push from a repository containing several branches > ending on the same short name. > > Note, this breaks existing setups. For example "master" will no longer > resolve to "origin/master". It may "break" but I think it is a good change. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska 2007-10-27 16:50 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Steffen Prohaska @ 2007-10-27 22:16 ` Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 0 replies; 36+ messages in thread From: Daniel Barkalow @ 2007-10-27 22:16 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git On Sat, 27 Oct 2007, Steffen Prohaska wrote: > ref_cmp_full_short(full_name, short_name) expands short_name according > to the rules documented in git-rev-parse and compares the expanded > name with full_name. It reports a match by returning 0. > > This function makes the rules for resolving refs to sha1s available > for string comparison. Before this change, the rules were buried in > get_sha1*() and dwim_ref(). > > ref_cmp_full_short() will be used for matching refspecs in git-send-pack. I think this and ref_matches_abbrev in remote.c should be both be named to be more explicit as to which sets of rules they implement, and should agree on order of arguments. -Daniel *This .sig left intentionally blank* ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska 2007-10-27 16:50 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Steffen Prohaska 2007-10-27 22:16 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Daniel Barkalow @ 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 0 replies; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > diff --git a/sha1_name.c b/sha1_name.c > index b820909..2a1e093 100644 > --- a/sha1_name.c > +++ b/sha1_name.c > @@ -249,6 +249,20 @@ static const char *ref_fmt[] = { > NULL > }; > > +int ref_cmp_full_short(const char *full_name, const char *short_name) > +{ > + const char **p; > + const int short_name_len = strlen(short_name); > + > + for (p = ref_fmt; *p; p++) { > + if (strcmp(full_name, mkpath(*p, short_name_len, short_name)) == 0) { We usually say "!strcmp()" instead for readability. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska @ 2007-10-27 22:03 ` Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 0 replies; 36+ messages in thread From: Daniel Barkalow @ 2007-10-27 22:03 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git On Sat, 27 Oct 2007, Steffen Prohaska wrote: > This teaches "push <remote> HEAD" to resolve HEAD on the local > side to its real ref name, e.g. refs/heads/master, and then > use the real ref name on the remote side to search a matching > remote ref. I'd prefer this to be in set_refspecs in builtin-push. That way, it only applies to command-line arguments and matches your description better. (If you use a symbolic name on the command line, it follows it, and acts exactly as if you used the name it points to). -Daniel *This .sig left intentionally blank* ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska 2007-10-27 22:03 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name Daniel Barkalow @ 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:03 ` Steffen Prohaska 2007-10-28 15:10 ` Steffen Prohaska 2 siblings, 2 replies; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > This teaches "push <remote> HEAD" to resolve HEAD on the local > side to its real ref name, e.g. refs/heads/master, and then > use the real ref name on the remote side to search a matching > remote ref. This probably is a good idea. > + if (real_name) { > + free(real_name); > + } Excess and unnecessary brace pair. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 7:28 ` Junio C Hamano @ 2007-10-28 8:03 ` Steffen Prohaska 2007-10-28 15:10 ` Steffen Prohaska 1 sibling, 0 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 8:03 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> This teaches "push <remote> HEAD" to resolve HEAD on the local >> side to its real ref name, e.g. refs/heads/master, and then >> use the real ref name on the remote side to search a matching >> remote ref. > > This probably is a good idea. I'll think about Daniel's suggestion of implementing it differently. >> + if (real_name) { >> + free(real_name); >> + } > > Excess and unnecessary brace pair. When are excess and unnecessary braces acceptable? Is if (something) { printf("text %d" "more text %d" "and even more %d\n" , a, b, c); } ok? Or should I avoid braces there, too? Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:03 ` Steffen Prohaska @ 2007-10-28 15:10 ` Steffen Prohaska 2007-10-28 15:40 ` Junio C Hamano 1 sibling, 1 reply; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 15:10 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> This teaches "push <remote> HEAD" to resolve HEAD on the local >> side to its real ref name, e.g. refs/heads/master, and then >> use the real ref name on the remote side to search a matching >> remote ref. > > This probably is a good idea. I'll add an even shorter shorthand: "git push HEAD" will push the current branch to its default remote. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 15:10 ` Steffen Prohaska @ 2007-10-28 15:40 ` Junio C Hamano 2007-10-28 15:59 ` Steffen Prohaska 2007-10-28 16:03 ` Junio C Hamano 0 siblings, 2 replies; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 15:40 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > >> Steffen Prohaska <prohaska@zib.de> writes: >> >>> This teaches "push <remote> HEAD" to resolve HEAD on the local >>> side to its real ref name, e.g. refs/heads/master, and then >>> use the real ref name on the remote side to search a matching >>> remote ref. >> >> This probably is a good idea. > > I'll add an even shorter shorthand: "git push HEAD" will push > the current branch to its default remote. Ugh, that looks way too magicky. The first parameter to push if one ever exists has _always_ been the remote, and the above breaks it. Please don't. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 15:40 ` Junio C Hamano @ 2007-10-28 15:59 ` Steffen Prohaska 2007-10-28 16:03 ` Junio C Hamano 1 sibling, 0 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 15:59 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 4:40 PM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: >> >>> Steffen Prohaska <prohaska@zib.de> writes: >>> >>>> This teaches "push <remote> HEAD" to resolve HEAD on the local >>>> side to its real ref name, e.g. refs/heads/master, and then >>>> use the real ref name on the remote side to search a matching >>>> remote ref. >>> >>> This probably is a good idea. >> >> I'll add an even shorter shorthand: "git push HEAD" will push >> the current branch to its default remote. > > Ugh, that looks way too magicky. The first parameter to push if > one ever exists has _always_ been the remote, and the above > breaks it. Yes. It breaks setups that have a remote named HEAD. > Please don't. I already did it -- it was too easy. But it's a separate patch. So it can easily be skipped. What would you propose for pushing only the current branch to its default remote repository? All information is there. Only a way to tell push to restrict push to the current branch is missing. Would you prefer something like "git push --only-current-branch"? Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 15:40 ` Junio C Hamano 2007-10-28 15:59 ` Steffen Prohaska @ 2007-10-28 16:03 ` Junio C Hamano 2007-10-28 16:30 ` Steffen Prohaska 1 sibling, 1 reply; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 16:03 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Junio C Hamano <gitster@pobox.com> writes: > Steffen Prohaska <prohaska@zib.de> writes: > >> On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: >> >>> Steffen Prohaska <prohaska@zib.de> writes: >>> >>>> This teaches "push <remote> HEAD" to resolve HEAD on the local >>>> side to its real ref name, e.g. refs/heads/master, and then >>>> use the real ref name on the remote side to search a matching >>>> remote ref. >>> >>> This probably is a good idea. >> >> I'll add an even shorter shorthand: "git push HEAD" will push >> the current branch to its default remote. > > Ugh, that looks way too magicky. The first parameter to push if > one ever exists has _always_ been the remote, and the above > breaks it. > > Please don't. An alternative, just to let me keep my nicer public image by pretending to be constructive ;-) Introduce a configuration "remote.$name.push_default" whose value can be a list of refs. Teach the push command without refspecs: $ git push $ git push $remote to pretend as if the listed refspecs are given, instead of the traditional "matching branches" behaviour. Then, introduce another option $ git push --matching $ git push --matching $remote to override that configuration, if set, so that the user who usually pushes only the selected branches can use the "matching branches" behaviour when needed. Along with your earlier "git push $remote HEAD" patch, this will allow you to say: [remote "origin"] push_default = HEAD and your $ git push will push only the current branch. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 16:03 ` Junio C Hamano @ 2007-10-28 16:30 ` Steffen Prohaska 2007-10-28 20:58 ` Junio C Hamano 0 siblings, 1 reply; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 16:30 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 5:03 PM, Junio C Hamano wrote: > Junio C Hamano <gitster@pobox.com> writes: > >> Steffen Prohaska <prohaska@zib.de> writes: >> >>> On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: >>> >>>> Steffen Prohaska <prohaska@zib.de> writes: >>>> >>>>> This teaches "push <remote> HEAD" to resolve HEAD on the local >>>>> side to its real ref name, e.g. refs/heads/master, and then >>>>> use the real ref name on the remote side to search a matching >>>>> remote ref. >>>> >>>> This probably is a good idea. >>> >>> I'll add an even shorter shorthand: "git push HEAD" will push >>> the current branch to its default remote. >> >> Ugh, that looks way too magicky. The first parameter to push if >> one ever exists has _always_ been the remote, and the above >> breaks it. >> >> Please don't. > > An alternative, just to let me keep my nicer public image by > pretending to be constructive ;-) > > Introduce a configuration "remote.$name.push_default" whose > value can be a list of refs. Teach the push command without > refspecs: > > $ git push > $ git push $remote > > to pretend as if the listed refspecs are given, instead of the > traditional "matching branches" behaviour. > > Then, introduce another option > > $ git push --matching > $ git push --matching $remote > > to override that configuration, if set, so that the user who > usually pushes only the selected branches can use the "matching > branches" behaviour when needed. > > Along with your earlier "git push $remote HEAD" patch, this will > allow you to say: > > [remote "origin"] > push_default = HEAD > > and your > > $ git push > > will push only the current branch. Sounds reasonable; but it is more work. I'm not starting to implement this today. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 16:30 ` Steffen Prohaska @ 2007-10-28 20:58 ` Junio C Hamano 2007-10-31 15:08 ` Steffen Prohaska 0 siblings, 1 reply; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 20:58 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > On Oct 28, 2007, at 5:03 PM, Junio C Hamano wrote: > ... >> An alternative, just to let me keep my nicer public image by >> pretending to be constructive ;-) >> >> Introduce a configuration "remote.$name.push_default" whose >> value can be a list of refs. Teach the push command without >> refspecs: >> >> $ git push >> $ git push $remote >> >> to pretend as if the listed refspecs are given, instead of the >> traditional "matching branches" behaviour. >> >> Then, introduce another option >> >> $ git push --matching >> $ git push --matching $remote >> >> to override that configuration, if set, so that the user who >> usually pushes only the selected branches can use the "matching >> branches" behaviour when needed. >> >> Along with your earlier "git push $remote HEAD" patch, this will >> allow you to say: >> >> [remote "origin"] >> push_default = HEAD >> >> and your >> >> $ git push >> >> will push only the current branch. > > Sounds reasonable; but it is more work. I'm not starting to > implement this today. Take your time; nobody is in a hurry. If somebody usually uses "matching" behaviour, i.e. without remote.$name.push_default configuration, but wants to push only the current branch as a one-shot operation, we can obviously use "git push $remote HEAD". But to be complete, it may make sense to have another option $ git push --current that lets you omit $remote (and default to the value configured with branch.$name.remote). ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name 2007-10-28 20:58 ` Junio C Hamano @ 2007-10-31 15:08 ` Steffen Prohaska 0 siblings, 0 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-31 15:08 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 9:58 PM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> On Oct 28, 2007, at 5:03 PM, Junio C Hamano wrote: >> ... >>> An alternative, just to let me keep my nicer public image by >>> pretending to be constructive ;-) >>> >>> Introduce a configuration "remote.$name.push_default" whose >>> value can be a list of refs. Teach the push command without >>> refspecs: >>> >>> $ git push >>> $ git push $remote >>> >>> to pretend as if the listed refspecs are given, instead of the >>> traditional "matching branches" behaviour. >>> >>> Then, introduce another option >>> >>> $ git push --matching >>> $ git push --matching $remote >>> >>> to override that configuration, if set, so that the user who >>> usually pushes only the selected branches can use the "matching >>> branches" behaviour when needed. >>> >>> Along with your earlier "git push $remote HEAD" patch, this will >>> allow you to say: >>> >>> [remote "origin"] >>> push_default = HEAD >>> >>> and your >>> >>> $ git push >>> >>> will push only the current branch. >> >> Sounds reasonable; but it is more work. I'm not starting to >> implement this today. > > Take your time; nobody is in a hurry. > > If somebody usually uses "matching" behaviour, i.e. without > remote.$name.push_default configuration, but wants to push only > the current branch as a one-shot operation, we can obviously use > "git push $remote HEAD". But to be complete, it may make sense > to have another option > > $ git push --current > > that lets you omit $remote (and default to the value configured > with branch.$name.remote). Here is an alternative proposal. The idea is that in a workflow based on a shared repository git pull and git push should be 'more' symmetric than they are in a pull-only based workflow. The integration of changes is 'more' direct. Working against a shared repository may require to integrate new changes before pushing. Changes are also pushed directly to the remote branch you originally branched off. Both is different from a pull-only workflow, where I first push my changes to a privately owned but publicly readable repo and someone else does the integration by pulling from there. The branch in the shared repository serves as the single 'integration' branch. One can use 'git branch --track' to set up local branches that automatically merge changes from the shared 'integration' branch. That is git pull without further arguments is the right command to integrate changes from the shared branch to the local branch. (git provides more advanced ways, but git pull is simple and in principle does the right thing.) What is missing is a simple way to 'push' local changes back to shared integration branch in the remote repository. This can be seen as a 'symmetric' operation to pulling. So, git push should do the right thing. And the right thing is pushing the current branch to the shared 'integration' branch. The automerge behaviour stores information in branch.$name.remote and branch.$name.merge that provide sufficient information to make "git pull" the equivalent of git pull <remoteURL> <remoteref> where <remoteURL> is the full URL of the remote stored in branch.$name.remote, and <remoteref> is the value of branch.$name.merge. A 'symmetric' push command would push the current branch to the remote head it originally was branched off, that is git push <remoteURL> <currentbranch>:<remoteref> Now, the proposal is - add a configuration variable branch.$name.push - change git push to check if the push configuration variable is set for the current branch $name, and if so run the equivalent of git push branch.$name.remote $name:branch.$name.push - teach git branch a flag --push/--no-push that sets up branch.$name.push. Add branch.autosetuppush configuration flag to configure if --push or --no-push is the default. (maybe we need better names here). This breaks the symmetry between git fetch/git push and replaces it with a symmetry between git pull/git push for some branches. I believe this might be the right thing to do for a workflow based on shared repos. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-27 16:50 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name Steffen Prohaska 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska @ 2007-10-27 21:53 ` Daniel Barkalow 2007-10-28 13:49 ` Steffen Prohaska 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 1 reply; 36+ messages in thread From: Daniel Barkalow @ 2007-10-27 21:53 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git On Sat, 27 Oct 2007, Steffen Prohaska wrote: > "git rev-parse --symbolic" used to return the ref name as it was > specified on the command line. This is changed to returning the > full matched ref name, i.e. "git rev-parse --symbolic master" > now typically returns "refs/heads/master". > > Note, this changes output of an established command. It might > break existing setups. I checked that it does not break scripts > in git.git. I think this makes the --create option to push unnecessary, as interactive users could use a suggested explicit value (or whatever they actually meant), while scripts could replace $name with $(git rev-parse --symbolic $name) as easily as they could add --create, and by more explicit as to what they're doing. -Daniel *This .sig left intentionally blank* ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-27 21:53 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full " Daniel Barkalow @ 2007-10-28 13:49 ` Steffen Prohaska 0 siblings, 0 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 13:49 UTC (permalink / raw) To: Daniel Barkalow; +Cc: git On Oct 27, 2007, at 11:53 PM, Daniel Barkalow wrote: > On Sat, 27 Oct 2007, Steffen Prohaska wrote: > >> "git rev-parse --symbolic" used to return the ref name as it was >> specified on the command line. This is changed to returning the >> full matched ref name, i.e. "git rev-parse --symbolic master" >> now typically returns "refs/heads/master". >> >> Note, this changes output of an established command. It might >> break existing setups. I checked that it does not break scripts >> in git.git. > > I think this makes the --create option to push unnecessary, as > interactive > users could use a suggested explicit value (or whatever they actually > meant), while scripts could replace $name with $(git rev-parse -- > symbolic > $name) as easily as they could add --create, and by more explicit > as to > what they're doing. I'll remove 4/8 (git rev-parse --symbolic) from the patch series. It is not directly related to the push behaviour and Junio pointed out that the old behavior of git rev-parse must be maintained as is. I'm not particularly interested in modifying git rev-parse. If someone else is, feel free to take over my patch. I'll keep the '--create' flag. Its intention is obvious and easy to explain to users. Much easier than "git rev-parse --dwim_ref ..." or something similar. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-27 16:50 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name Steffen Prohaska 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska 2007-10-27 21:53 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full " Daniel Barkalow @ 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 7:58 ` Steffen Prohaska 2 siblings, 1 reply; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > "git rev-parse --symbolic" used to return the ref name as it was > specified on the command line. This is changed to returning the > full matched ref name, i.e. "git rev-parse --symbolic master" > now typically returns "refs/heads/master". This is to expose "dwim_ref" logic, so it might be a good idea to introduce a new option --dwim-ref for this purpose. git rev-parse --symbolic master^2 is designed to give "master^2" or fail if "master" is not a merge. Similarly, you would diagnose a failure if somebody asks to show git rev-parse --dwim-ref master~4 instead of giving "refs/heads/master~4". > +static void show_rev(int type, const unsigned char *sha1, const char *name, const char* real_name) > @@ -131,7 +133,7 @@ static void show_default(void) > > def = NULL; > if (!get_sha1(s, sha1)) { > - show_rev(NORMAL, sha1, s); > + show_rev(NORMAL, sha1, s, 0); A null pointer constant in git sources is spelled "NULL" not "0". > @@ -213,6 +215,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) > { > int i, as_is = 0, verify = 0; > unsigned char sha1[20]; > + char* real_name = 0; Pointer sign '*' in git sources go next to the name not the type, as: char *real_name = NULL; ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-28 7:28 ` Junio C Hamano @ 2007-10-28 7:58 ` Steffen Prohaska 2007-10-28 8:06 ` Shawn O. Pearce 2007-10-28 8:24 ` Junio C Hamano 0 siblings, 2 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 7:58 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> "git rev-parse --symbolic" used to return the ref name as it was >> specified on the command line. This is changed to returning the >> full matched ref name, i.e. "git rev-parse --symbolic master" >> now typically returns "refs/heads/master". > > This is to expose "dwim_ref" logic, so it might be a good idea > to introduce a new option --dwim-ref for this purpose. > > git rev-parse --symbolic master^2 > > is designed to give "master^2" or fail if "master" is not a > merge. So the idea of --symbolic is really to return the argv as is? No change whatsoever allowed. Why would someone need this? Is it only for convenience when writing shell code? > Similarly, you would diagnose a failure if somebody asks > to show > > git rev-parse --dwim-ref master~4 > > instead of giving "refs/heads/master~4". What I proposed is to teach git rev-parse to return a full symbolic ref name. Maybe git rev-parse --full-symbolic git rev-parse --full-ref But honestly, I don't care that much about this patch. Maybe we just put it aside? >> +static void show_rev(int type, const unsigned char *sha1, const >> char *name, const char* real_name) >> @@ -131,7 +133,7 @@ static void show_default(void) >> >> def = NULL; >> if (!get_sha1(s, sha1)) { >> - show_rev(NORMAL, sha1, s); >> + show_rev(NORMAL, sha1, s, 0); > > A null pointer constant in git sources is spelled "NULL" not "0". Ok. I'll fix this in all patches. >> @@ -213,6 +215,7 @@ int cmd_rev_parse(int argc, const char **argv, >> const char *prefix) >> { >> int i, as_is = 0, verify = 0; >> unsigned char sha1[20]; >> + char* real_name = 0; > > Pointer sign '*' in git sources go next to the name not the > type, as: > > char *real_name = NULL; I know and I tried hard to follow this convention, although I think its the wrong choice ;) Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-28 7:58 ` Steffen Prohaska @ 2007-10-28 8:06 ` Shawn O. Pearce 2007-10-28 8:56 ` Steffen Prohaska 2007-10-28 8:24 ` Junio C Hamano 1 sibling, 1 reply; 36+ messages in thread From: Shawn O. Pearce @ 2007-10-28 8:06 UTC (permalink / raw) To: Steffen Prohaska; +Cc: Junio C Hamano, git Steffen Prohaska <prohaska@zib.de> wrote: > On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > >Steffen Prohaska <prohaska@zib.de> writes: > >>@@ -213,6 +215,7 @@ int cmd_rev_parse(int argc, const char **argv, > >>const char *prefix) > >> { > >> int i, as_is = 0, verify = 0; > >> unsigned char sha1[20]; > >>+ char* real_name = 0; > > > >Pointer sign '*' in git sources go next to the name not the > >type, as: > > > > char *real_name = NULL; > > I know and I tried hard to follow this convention, although > I think its the wrong choice ;) Oh, hmm... char* a, b; What's the type of b? If you said "char*" you're wrong. Git's style of putting the * next to the name makes it far easier to spot these sort of typing problems. At least that's my take on it. -- Shawn. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-28 8:06 ` Shawn O. Pearce @ 2007-10-28 8:56 ` Steffen Prohaska 2007-10-28 15:10 ` Brian Gernhardt 0 siblings, 1 reply; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 8:56 UTC (permalink / raw) To: Shawn O. Pearce; +Cc: Junio C Hamano, git On Oct 28, 2007, at 9:06 AM, Shawn O. Pearce wrote: > Steffen Prohaska <prohaska@zib.de> wrote: >> On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: >>> Steffen Prohaska <prohaska@zib.de> writes: >>>> @@ -213,6 +215,7 @@ int cmd_rev_parse(int argc, const char **argv, >>>> const char *prefix) >>>> { >>>> int i, as_is = 0, verify = 0; >>>> unsigned char sha1[20]; >>>> + char* real_name = 0; >>> >>> Pointer sign '*' in git sources go next to the name not the >>> type, as: >>> >>> char *real_name = NULL; >> >> I know and I tried hard to follow this convention, although >> I think its the wrong choice ;) > > Oh, hmm... > > char* a, b; > > What's the type of b? If you said "char*" you're wrong. I know. Obviously, you need a combination of conventions. - '*' is part of the type; put it there. - Only define a single variable per statement. My combined rule avoids your question. I typically use C++, which make the second rule easier to follow, because you defer defining variables until you really need them. There's no need to save space at the start of the function block by defining several variables in a single line. > Git's style of putting the * next to the name makes it far easier to > spot these sort of typing problems. At least that's my take on it. Let's stop this discussion here. I'm not proposing to change the rules. I'll follow the git coding conventions when submitting patches to git, even if it's sometimes hard for me. I already packed as much as possible in my editor configuration. Unfortunately, I can't teach vim to always place the '*' correctly. At least I don't know how to do this. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-28 8:56 ` Steffen Prohaska @ 2007-10-28 15:10 ` Brian Gernhardt 0 siblings, 0 replies; 36+ messages in thread From: Brian Gernhardt @ 2007-10-28 15:10 UTC (permalink / raw) To: Steffen Prohaska; +Cc: Shawn O. Pearce, Junio C Hamano, git On Oct 28, 2007, at 4:56 AM, Steffen Prohaska wrote: > I can't teach vim to always place the '*' correctly. At least I > don't know how to do this. I did some research (I was curious), and the following in your .vimrc will do it: (Mildly tested) -----8<----- " Needed to avoid 'char * ' func s:Eatchar(pat) let c = nr2char(getchar(0)) return (c =~ a:pat) ? '' : c endfunc " Make creating the abbreviation for multiple types easier func s:FixPointer(type) exec "iabbr " . a:type . "* " . a:type . " *<C-R>=<SID>Eatchar('\ \s')<CR>" endfunc command -nargs=1 FixPointer call <SID>FixPointer(<args>) " Change the following pointer types (char* var -> char *var) FixPointer 'char' FixPointer 'int' FixPointer 'void' -----8<----- Repeating the last line for each type you want to fix the pointers for. There may be a simpler way to do some of this, but I don't know it. But once it's set up each time you type in "char* var", Vim will auto-correct to "char *var". Changing this to operate only in C, or only if you're starting in your git repository is left as an exercise for the reader. ;-) ~~ Brian ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name 2007-10-28 7:58 ` Steffen Prohaska 2007-10-28 8:06 ` Shawn O. Pearce @ 2007-10-28 8:24 ` Junio C Hamano 1 sibling, 0 replies; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 8:24 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > So the idea of --symbolic is really to return the argv as is? > No change whatsoever allowed. Why would someone need this? > Is it only for convenience when writing shell code? rev-parse _is_ for convenience for writing shell scripts, to sift various parameters into "rev-list arguments" and "non rev-list arguments". ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand 2007-10-27 16:50 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Steffen Prohaska 2007-10-27 16:50 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name Steffen Prohaska @ 2007-10-28 7:28 ` Junio C Hamano 1 sibling, 0 replies; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > The new function can be used by "git rev-parse" to print the full > name of the matched ref and can be used by "git send-pack" to expand > a local ref to its full name. "can be"? "will be used to implement git rev-parse --some-option"? > +static int get_sha1_1(const char *name, int len, unsigned char *sha1, char **real_ref); > > static int get_parent(const char *name, int len, > unsigned char *result, int idx) > { > unsigned char sha1[20]; > - int ret = get_sha1_1(name, len, sha1); > + int ret = get_sha1_1(name, len, sha1, /*real_ref=*/ 0); A null pointer constant in git sources is spelled as "NULL", not "0". ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 1/8] push: change push to fail if short ref name does not exist 2007-10-27 16:50 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Steffen Prohaska 2007-10-27 16:50 ` [PATCH 2/8] push: teach push new flag --create Steffen Prohaska @ 2007-10-27 21:42 ` Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2 siblings, 0 replies; 36+ messages in thread From: Daniel Barkalow @ 2007-10-27 21:42 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git On Sat, 27 Oct 2007, Steffen Prohaska wrote: > You can use a branch's shortname to push it. Push used to create > the branch on the remote side if it did not yet exist. If you > specified the wrong branch accidentally it was created. A safety > valve that pushes only existing branches may help to avoid > errors. > > This commit changes push to fail if the remote ref does not yet > exist and the refspec does not start with refs/. Remote refs must > explicitly be created with their full name. I agree with the change (and I think it's appropriate for master or next), but your implementation is a bit too clever for my tastes. > Signed-off-by: Steffen Prohaska <prohaska@zib.de> > --- > remote.c | 5 +++-- > t/t5516-fetch-push.sh | 34 ++++++++++++++++++++++++++++++++-- > 2 files changed, 35 insertions(+), 4 deletions(-) > > diff --git a/remote.c b/remote.c > index 170015a..ec992c9 100644 > --- a/remote.c > +++ b/remote.c > @@ -611,6 +611,7 @@ static int match_explicit(struct ref *src, struct ref *dst, > struct ref *matched_src, *matched_dst; > > const char *dst_value = rs->dst; > + const char * const orig_dst_value = rs->dst ? rs->dst : rs->src; "lit_dst_value" would probably be a better description, and it might be worth handling the rs->dst == NULL case where it's handled for dst_value. Technically, this variable, when it doesn't match the final value of dst_value, has a value that dst_value never had. > > if (rs->pattern) > return errs; > @@ -647,12 +648,12 @@ static int match_explicit(struct ref *src, struct ref *dst, > case 1: > break; > case 0: > - if (!memcmp(dst_value, "refs/", 5)) > + if (!memcmp(orig_dst_value , "refs/", 5)) > matched_dst = make_linked_ref(dst_value, dst_tail); This should also be orig_dst_value, too. I know that dst_value and orig_dst_value must be the same in this case, but it takes a bunch of analysis to demonstrate that, and it's more intuitive to use the value you've just checked anyway, and also to have all of case 0 use the differently-computed destination. > else > error("dst refspec %s does not match any " > "existing ref on the remote and does " > - "not start with refs/.", dst_value); > + "not start with refs/.", orig_dst_value); Maybe the error should provide a hint if dst_value is not the same as orig_dst_value? (if (!rs->dst) error("Did you mean %s?\n", dst_value);) -Daniel *This .sig left intentionally blank* ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 1/8] push: change push to fail if short ref name does not exist 2007-10-27 16:50 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Steffen Prohaska 2007-10-27 16:50 ` [PATCH 2/8] push: teach push new flag --create Steffen Prohaska 2007-10-27 21:42 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Daniel Barkalow @ 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:43 ` Steffen Prohaska 2 siblings, 1 reply; 36+ messages in thread From: Junio C Hamano @ 2007-10-28 7:28 UTC (permalink / raw) To: Steffen Prohaska; +Cc: git Steffen Prohaska <prohaska@zib.de> writes: > You can use a branch's shortname to push it. Push used to create > the branch on the remote side if it did not yet exist. If you > specified the wrong branch accidentally it was created. A safety > valve that pushes only existing branches may help to avoid > errors. I do not agree with this change. If you misspelled the branch name (by the way, it is not a "shortname", but what follows refs/heads/ is _the_ name of the branch) "frotz" as "frtoz", and if a branch with the misspelled name did _not_ exist locally, it would fail, with or without this change, which is a good thing. But if you named "nitfol" that exists locally when you meant to push "frotz" out, if "nitfol" remotely existed, we will push that anyway by mistake, even with this change. It will prevent the push only when "nitfol" did not happen to exist at the remote side. Earlier there was a discussion to introduce an optional configuration that makes "git push" without any parameter to push only the current branch out, in order to help people who work with shared remote central repository. That might be a better alternative to avoid pushing out wrong branch by mistake. That approach would also make your 8/8 unnecessary. ^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH 1/8] push: change push to fail if short ref name does not exist 2007-10-28 7:28 ` Junio C Hamano @ 2007-10-28 8:43 ` Steffen Prohaska 0 siblings, 0 replies; 36+ messages in thread From: Steffen Prohaska @ 2007-10-28 8:43 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On Oct 28, 2007, at 8:28 AM, Junio C Hamano wrote: > Steffen Prohaska <prohaska@zib.de> writes: > >> You can use a branch's shortname to push it. Push used to create >> the branch on the remote side if it did not yet exist. If you >> specified the wrong branch accidentally it was created. A safety >> valve that pushes only existing branches may help to avoid >> errors. > > I do not agree with this change. > > If you misspelled the branch name (by the way, it is not a > "shortname", but what follows refs/heads/ is _the_ name of the > branch) True. Is "short refname" the correct wording? > "frotz" as "frtoz", and if a branch with the misspelled > name did _not_ exist locally, it would fail, with or without > this change, which is a good thing. > > But if you named "nitfol" that exists locally when you meant to > push "frotz" out, if "nitfol" remotely existed, we will push > that anyway by mistake, even with this change. It will prevent > the push only when "nitfol" did not happen to exist at the > remote side. My proposed change is more defensive than the current implementation. It allows distinguishing between "push existing branch" and "create new branch on the remote side", which I believe is a good thing. The current implementation uses the same command line in both cases. Daniel suggested that git push should print a recommendation what full ref to use. This would make it easy to correct the command. Ot you could use the '--create' flag to make your intention explicit. If we take the "push origin HEAD" patch, the existence check is even more important. If you're on the wrong branch and push HEAD you may be surprised if a new branch is created. This can be avoided by requiring either a full ref or the '--create' flag. > Earlier there was a discussion to introduce an optional > configuration that makes "git push" without any parameter to > push only the current branch out, in order to help people who > work with shared remote central repository. That might be a > better alternative to avoid pushing out wrong branch by > mistake. That approach would also make your 8/8 unnecessary. I didn't have the impression that the discussion went in this direction. There were quite a few people who just said "git push" is the counter-part of "git fetch". Therefore "git push" pushes _all_ branches. Period. With "git push HEAD" 5/8 you could now push only the current branch (its existence would be verified if 1/8 is also accepted). 8/8 solves a different issue, too. I never advance local branches if I do not intend to push them. Therefore I can always say "git push" without any argument. It does always the right thing for me; except for the annoying error messages that are avoided by 8/8. With 8/8 I can push several local branches while ignoring the ones that I'm not interested in. Steffen ^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2007-10-31 15:08 UTC | newest] Thread overview: 36+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-10-27 16:49 [PATCH 0/8 v2] improve push's refspec handling Steffen Prohaska 2007-10-27 16:50 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Steffen Prohaska 2007-10-27 16:50 ` [PATCH 2/8] push: teach push new flag --create Steffen Prohaska 2007-10-27 16:50 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Steffen Prohaska 2007-10-27 16:50 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full ref name Steffen Prohaska 2007-10-27 16:50 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real " Steffen Prohaska 2007-10-27 16:50 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Steffen Prohaska 2007-10-27 16:50 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Steffen Prohaska 2007-10-27 16:50 ` [PATCH 8/8] push: teach push to be quiet if local ref is strict subset of remote ref Steffen Prohaska 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:20 ` Steffen Prohaska 2007-10-28 7:28 ` [PATCH 7/8] push: use same rules as git-rev-parse to resolve refspecs Junio C Hamano 2007-10-27 22:16 ` [PATCH 6/8] add ref_cmp_full_short() comparing full ref name with a short name Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2007-10-27 22:03 ` [PATCH 5/8] push, send-pack: support pushing HEAD to real ref name Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:03 ` Steffen Prohaska 2007-10-28 15:10 ` Steffen Prohaska 2007-10-28 15:40 ` Junio C Hamano 2007-10-28 15:59 ` Steffen Prohaska 2007-10-28 16:03 ` Junio C Hamano 2007-10-28 16:30 ` Steffen Prohaska 2007-10-28 20:58 ` Junio C Hamano 2007-10-31 15:08 ` Steffen Prohaska 2007-10-27 21:53 ` [PATCH 4/8] rev-parse: teach "git rev-parse --symbolic" to print the full " Daniel Barkalow 2007-10-28 13:49 ` Steffen Prohaska 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 7:58 ` Steffen Prohaska 2007-10-28 8:06 ` Shawn O. Pearce 2007-10-28 8:56 ` Steffen Prohaska 2007-10-28 15:10 ` Brian Gernhardt 2007-10-28 8:24 ` Junio C Hamano 2007-10-28 7:28 ` [PATCH 3/8] add get_sha1_with_real_ref() returning full name of ref on demand Junio C Hamano 2007-10-27 21:42 ` [PATCH 1/8] push: change push to fail if short ref name does not exist Daniel Barkalow 2007-10-28 7:28 ` Junio C Hamano 2007-10-28 8:43 ` Steffen Prohaska
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).