From: Junio C Hamano Date: Tue, 19 Mar 2013 19:15:54 +0000 (-0700) Subject: Merge branch 'da/downcase-u-in-usage' X-Git-Tag: v1.8.3-rc0~222 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/c2bf648b84d3b61c4250f0e921a40b75d3e72cf8?hp=-c Merge branch 'da/downcase-u-in-usage' * da/downcase-u-in-usage: contrib/mw-to-git/t/install-wiki.sh: use a lowercase "usage:" string contrib/examples/git-remote.perl: use a lowercase "usage:" string tests: use a lowercase "usage:" string git-svn: use a lowercase "usage:" string Documentation/user-manual.txt: use a lowercase "usage:" string templates/hooks--update.sample: use a lowercase "usage:" string contrib/hooks/setgitperms.perl: use a lowercase "usage:" string contrib/examples: use a lowercase "usage:" string contrib/fast-import/import-zips.py: use spaces instead of tabs contrib/fast-import/import-zips.py: fix broken error message contrib/fast-import: use a lowercase "usage:" string contrib/credential: use a lowercase "usage:" string git-cvsimport: use a lowercase "usage:" string git-cvsimport: use a lowercase "usage:" string git-cvsexportcommit: use a lowercase "usage:" string git-archimport: use a lowercase "usage:" string git-merge-one-file: use a lowercase "usage:" string git-relink: use a lowercase "usage:" string git-svn: use a lowercase "usage:" string git-sh-setup: use a lowercase "usage:" string --- c2bf648b84d3b61c4250f0e921a40b75d3e72cf8 diff --combined Documentation/user-manual.txt index 5f36f8115f,d290632d18..35a279ab24 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.txt @@@ -2006,7 -2006,7 +2006,7 @@@ Note that the target of a "push" is nor <> repository. You can also push to a repository that has a checked-out working tree, but a push to update the currently checked-out branch is denied by default to prevent confusion. -See the description ofthe receive.denyCurrentBranch option +See the description of the receive.denyCurrentBranch option in linkgit:git-config[1] for details. As with `git fetch`, you may also set up configuration options to @@@ -2306,13 -2306,17 +2306,13 @@@ branch and then merge into each of the these changes, just apply directly to the "release" branch, and then merge that into the "test" branch. -To create diffstat and shortlog summaries of changes to include in a "please -pull" request to Linus you can use: +After pushing your work to `mytree`, you can use +linkgit:git-request-pull[1] to prepare a "please pull" request message +to send to Linus: ------------------------------------------------- -$ git diff --stat origin..release -------------------------------------------------- - -and - -------------------------------------------------- -$ git log -p origin..release | git shortlog +$ git push mytree +$ git request-pull origin mytree release ------------------------------------------------- Here are some of the scripts that simplify all this even further. @@@ -2337,7 -2341,7 +2337,7 @@@ origin fi ;; *) - echo "Usage: $0 origin|test|release" 1>&2 + echo "usage: $0 origin|test|release" 1>&2 exit 1 ;; esac @@@ -2351,7 -2355,7 +2351,7 @@@ pname=$ usage() { - echo "Usage: $pname branch test|release" 1>&2 + echo "usage: $pname branch test|release" 1>&2 exit 1 } @@@ -2553,12 -2557,6 +2553,12 @@@ return mywork to the state it had befor $ git rebase --abort ------------------------------------------------- +If you need to reorder or edit a number of commits in a branch, it may +be easier to use `git rebase -i`, which allows you to reorder and +squash commits, as well as marking them for individual editing during +the rebase. See <> for details, and +<> for alternatives. + [[rewriting-one-commit]] Rewriting a single commit ------------------------- @@@ -2572,89 -2570,72 +2572,89 @@@ $ git commit --amen which will replace the old commit by a new commit incorporating your changes, giving you a chance to edit the old commit message first. +This is useful for fixing typos in your last commit, or for adjusting +the patch contents of a poorly staged commit. -You can also use a combination of this and linkgit:git-rebase[1] to -replace a commit further back in your history and recreate the -intervening changes on top of it. First, tag the problematic commit -with +If you need to amend commits from deeper in your history, you can +use <>. -------------------------------------------------- -$ git tag bad mywork~5 -------------------------------------------------- - -(Either gitk or `git log` may be useful for finding the commit.) +[[reordering-patch-series]] +Reordering or selecting from a patch series +------------------------------------------- -Then check out that commit, edit it, and rebase the rest of the series -on top of it (note that we could check out the commit on a temporary -branch, but instead we're using a <>): +Sometimes you want to edit a commit deeper in your history. One +approach is to use `git format-patch` to create a series of patches +and then reset the state to before the patches: ------------------------------------------------- -$ git checkout bad -$ # make changes here and update the index -$ git commit --amend -$ git rebase --onto HEAD bad mywork +$ git format-patch origin +$ git reset --hard origin ------------------------------------------------- -When you're done, you'll be left with mywork checked out, with the top -patches on mywork reapplied on top of your modified commit. You can -then clean up with +Then modify, reorder, or eliminate patches as needed before applying +them again with linkgit:git-am[1]: ------------------------------------------------- -$ git tag -d bad +$ git am *.patch ------------------------------------------------- -Note that the immutable nature of Git history means that you haven't really -"modified" existing commits; instead, you have replaced the old commits with -new commits having new object names. +[[interactive-rebase]] +Using interactive rebases +------------------------- -[[reordering-patch-series]] -Reordering or selecting from a patch series -------------------------------------------- +You can also edit a patch series with an interactive rebase. This is +the same as <>, so use whichever interface you like best. -Given one existing commit, the linkgit:git-cherry-pick[1] command -allows you to apply the change introduced by that commit and create a -new commit that records it. So, for example, if "mywork" points to a -series of patches on top of "origin", you might do something like: +Rebase your current HEAD on the last commit you want to retain as-is. +For example, if you want to reorder the last 5 commits, use: ------------------------------------------------- -$ git checkout -b mywork-new origin -$ gitk origin..mywork & +$ git rebase -i HEAD~5 ------------------------------------------------- -and browse through the list of patches in the mywork branch using gitk, -applying them (possibly in a different order) to mywork-new using -cherry-pick, and possibly modifying them as you go using `git commit --amend`. -The linkgit:git-gui[1] command may also help as it allows you to -individually select diff hunks for inclusion in the index (by -right-clicking on the diff hunk and choosing "Stage Hunk for Commit"). - -Another technique is to use `git format-patch` to create a series of -patches, then reset the state to before the patches: +This will open your editor with a list of steps to be taken to perform +your rebase. ------------------------------------------------- -$ git format-patch origin -$ git reset --hard origin -------------------------------------------------- +pick deadbee The oneline of this commit +pick fa1afe1 The oneline of the next commit +... -Then modify, reorder, or eliminate patches as preferred before applying -them again with linkgit:git-am[1]. +# Rebase c0ffeee..deadbee onto c0ffeee +# +# Commands: +# p, pick = use commit +# r, reword = use commit, but edit the commit message +# e, edit = use commit, but stop for amending +# s, squash = use commit, but meld into previous commit +# f, fixup = like "squash", but discard this commit's log message +# x, exec = run command (the rest of the line) using shell +# +# These lines can be re-ordered; they are executed from top to bottom. +# +# If you remove a line here THAT COMMIT WILL BE LOST. +# +# However, if you remove everything, the rebase will be aborted. +# +# Note that empty commits are commented out +------------------------------------------------- + +As explained in the comments, you can reorder commits, squash them +together, edit commit messages, etc. by editing the list. Once you +are satisfied, save the list and close your editor, and the rebase +will begin. + +The rebase will stop where `pick` has been replaced with `edit` or +when a step in the list fails to mechanically resolve conflicts and +needs your help. When you are done editing and/or resolving conflicts +you can continue with `git rebase --continue`. If you decide that +things are getting too hairy, you can always bail out with `git rebase +--abort`. Even after the rebase is complete, you can still recover +the original branch by using the <>. + +For a more detailed discussion of the procedure and additional tips, +see the "INTERACTIVE MODE" section of linkgit:git-rebase[1]. [[patch-series-tools]] Other tools @@@ -3740,9 -3721,7 +3740,9 @@@ module NOTE: The changes are still visible in the submodule's reflog. -This is not the case if you did not commit your changes. +If you have uncommitted changes in your submodule working tree, `git +submodule update` will not overwrite them. Instead, you get the usual +warning about not being able switch from a dirty branch. [[low-level-operations]] Low-level Git operations diff --combined contrib/credential/wincred/git-credential-wincred.c index dac19eac81,66194929fc..a1d38f035b --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@@ -9,8 -9,6 +9,8 @@@ /* common helpers */ +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + static void die(const char *err, ...) { char msg[4096]; @@@ -32,6 -30,14 +32,6 @@@ static void *xmalloc(size_t size return ret; } -static char *xstrdup(const char *str) -{ - char *ret = strdup(str); - if (!ret) - die("Out of memory"); - return ret; -} - /* MinGW doesn't have wincred.h, so we need to define stuff */ typedef struct _CREDENTIAL_ATTRIBUTEW { @@@ -61,14 -67,20 +61,14 @@@ typedef struct _CREDENTIALW #define CRED_MAX_ATTRIBUTES 64 typedef BOOL (WINAPI *CredWriteWT)(PCREDENTIALW, DWORD); -typedef BOOL (WINAPI *CredUnPackAuthenticationBufferWT)(DWORD, PVOID, DWORD, - LPWSTR, DWORD *, LPWSTR, DWORD *, LPWSTR, DWORD *); typedef BOOL (WINAPI *CredEnumerateWT)(LPCWSTR, DWORD, DWORD *, PCREDENTIALW **); -typedef BOOL (WINAPI *CredPackAuthenticationBufferWT)(DWORD, LPWSTR, LPWSTR, - PBYTE, DWORD *); typedef VOID (WINAPI *CredFreeT)(PVOID); typedef BOOL (WINAPI *CredDeleteWT)(LPCWSTR, DWORD, DWORD); -static HMODULE advapi, credui; +static HMODULE advapi; static CredWriteWT CredWriteW; -static CredUnPackAuthenticationBufferWT CredUnPackAuthenticationBufferW; static CredEnumerateWT CredEnumerateW; -static CredPackAuthenticationBufferWT CredPackAuthenticationBufferW; static CredFreeT CredFree; static CredDeleteWT CredDeleteW; @@@ -76,84 -88,74 +76,84 @@@ static void load_cred_funcs(void { /* load DLLs */ advapi = LoadLibrary("advapi32.dll"); - credui = LoadLibrary("credui.dll"); - if (!advapi || !credui) - die("failed to load DLLs"); + if (!advapi) + die("failed to load advapi32.dll"); /* get function pointers */ CredWriteW = (CredWriteWT)GetProcAddress(advapi, "CredWriteW"); - CredUnPackAuthenticationBufferW = (CredUnPackAuthenticationBufferWT) - GetProcAddress(credui, "CredUnPackAuthenticationBufferW"); CredEnumerateW = (CredEnumerateWT)GetProcAddress(advapi, "CredEnumerateW"); - CredPackAuthenticationBufferW = (CredPackAuthenticationBufferWT) - GetProcAddress(credui, "CredPackAuthenticationBufferW"); CredFree = (CredFreeT)GetProcAddress(advapi, "CredFree"); CredDeleteW = (CredDeleteWT)GetProcAddress(advapi, "CredDeleteW"); - if (!CredWriteW || !CredUnPackAuthenticationBufferW || - !CredEnumerateW || !CredPackAuthenticationBufferW || !CredFree || - !CredDeleteW) + if (!CredWriteW || !CredEnumerateW || !CredFree || !CredDeleteW) die("failed to load functions"); } -static char target_buf[1024]; -static char *protocol, *host, *path, *username; -static WCHAR *wusername, *password, *target; +static WCHAR *wusername, *password, *protocol, *host, *path, target[1024]; -static void write_item(const char *what, WCHAR *wbuf) +static void write_item(const char *what, LPCWSTR wbuf, int wlen) { char *buf; - int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, NULL, 0, NULL, + int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, NULL, 0, NULL, FALSE); buf = xmalloc(len); - if (!WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, len, NULL, FALSE)) + if (!WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, buf, len, NULL, FALSE)) die("WideCharToMultiByte failed!"); printf("%s=", what); - fwrite(buf, 1, len - 1, stdout); + fwrite(buf, 1, len, stdout); putchar('\n'); free(buf); } -static int match_attr(const CREDENTIALW *cred, const WCHAR *keyword, - const char *want) +/* + * Match an (optional) expected string and a delimiter in the target string, + * consuming the matched text by updating the target pointer. + */ +static int match_part(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim) { - int i; - if (!want) - return 1; - - for (i = 0; i < cred->AttributeCount; ++i) - if (!wcscmp(cred->Attributes[i].Keyword, keyword)) - return !strcmp((const char *)cred->Attributes[i].Value, - want); - - return 0; /* not found */ + LPCWSTR delim_pos, start = *ptarget; + int len; + + /* find start of delimiter (or end-of-string if delim is empty) */ + if (*delim) + delim_pos = wcsstr(start, delim); + else + delim_pos = start + wcslen(start); + + /* + * match text up to delimiter, or end of string (e.g. the '/' after + * host is optional if not followed by a path) + */ + if (delim_pos) + len = delim_pos - start; + else + len = wcslen(start); + + /* update ptarget if we either found a delimiter or need a match */ + if (delim_pos || want) + *ptarget = delim_pos ? delim_pos + wcslen(delim) : start + len; + + return !want || (!wcsncmp(want, start, len) && !want[len]); } static int match_cred(const CREDENTIALW *cred) { - return (!wusername || !wcscmp(wusername, cred->UserName)) && - match_attr(cred, L"git_protocol", protocol) && - match_attr(cred, L"git_host", host) && - match_attr(cred, L"git_path", path); + LPCWSTR target = cred->TargetName; + if (wusername && wcscmp(wusername, cred->UserName)) + return 0; + + return match_part(&target, L"git", L":") && + match_part(&target, protocol, L"://") && + match_part(&target, wusername, L"@") && + match_part(&target, host, L"/") && + match_part(&target, path, L""); } static void get_credential(void) { - WCHAR *user_buf, *pass_buf; - DWORD user_buf_size = 0, pass_buf_size = 0; - CREDENTIALW **creds, *cred = NULL; + CREDENTIALW **creds; DWORD num_creds; int i; @@@ -163,36 -165,90 +163,36 @@@ /* search for the first credential that matches username */ for (i = 0; i < num_creds; ++i) if (match_cred(creds[i])) { - cred = creds[i]; + write_item("username", creds[i]->UserName, + wcslen(creds[i]->UserName)); + write_item("password", + (LPCWSTR)creds[i]->CredentialBlob, + creds[i]->CredentialBlobSize / sizeof(WCHAR)); break; } - if (!cred) - return; - - CredUnPackAuthenticationBufferW(0, cred->CredentialBlob, - cred->CredentialBlobSize, NULL, &user_buf_size, NULL, NULL, - NULL, &pass_buf_size); - - user_buf = xmalloc(user_buf_size * sizeof(WCHAR)); - pass_buf = xmalloc(pass_buf_size * sizeof(WCHAR)); - - if (!CredUnPackAuthenticationBufferW(0, cred->CredentialBlob, - cred->CredentialBlobSize, user_buf, &user_buf_size, NULL, NULL, - pass_buf, &pass_buf_size)) - die("CredUnPackAuthenticationBuffer failed"); CredFree(creds); - - /* zero-terminate (sizes include zero-termination) */ - user_buf[user_buf_size - 1] = L'\0'; - pass_buf[pass_buf_size - 1] = L'\0'; - - write_item("username", user_buf); - write_item("password", pass_buf); - - free(user_buf); - free(pass_buf); -} - -static void write_attr(CREDENTIAL_ATTRIBUTEW *attr, const WCHAR *keyword, - const char *value) -{ - attr->Keyword = (LPWSTR)keyword; - attr->Flags = 0; - attr->ValueSize = strlen(value) + 1; /* store zero-termination */ - attr->Value = (LPBYTE)value; } static void store_credential(void) { CREDENTIALW cred; - BYTE *auth_buf; - DWORD auth_buf_size = 0; - CREDENTIAL_ATTRIBUTEW attrs[CRED_MAX_ATTRIBUTES]; if (!wusername || !password) return; - /* query buffer size */ - CredPackAuthenticationBufferW(0, wusername, password, - NULL, &auth_buf_size); - - auth_buf = xmalloc(auth_buf_size); - - if (!CredPackAuthenticationBufferW(0, wusername, password, - auth_buf, &auth_buf_size)) - die("CredPackAuthenticationBuffer failed"); - cred.Flags = 0; cred.Type = CRED_TYPE_GENERIC; cred.TargetName = target; cred.Comment = L"saved by git-credential-wincred"; - cred.CredentialBlobSize = auth_buf_size; - cred.CredentialBlob = auth_buf; + cred.CredentialBlobSize = (wcslen(password)) * sizeof(WCHAR); + cred.CredentialBlob = (LPVOID)password; cred.Persist = CRED_PERSIST_LOCAL_MACHINE; - cred.AttributeCount = 1; - cred.Attributes = attrs; + cred.AttributeCount = 0; + cred.Attributes = NULL; cred.TargetAlias = NULL; cred.UserName = wusername; - write_attr(attrs, L"git_protocol", protocol); - - if (host) { - write_attr(attrs + cred.AttributeCount, L"git_host", host); - cred.AttributeCount++; - } - - if (path) { - write_attr(attrs + cred.AttributeCount, L"git_path", path); - cred.AttributeCount++; - } - if (!CredWriteW(&cred, 0)) die("CredWrite failed"); } @@@ -228,13 -284,10 +228,13 @@@ static void read_credential(void while (fgets(buf, sizeof(buf), stdin)) { char *v; + int len = strlen(buf); + /* strip trailing CR / LF */ + while (len && strchr("\r\n", buf[len - 1])) + buf[--len] = 0; - if (!strcmp(buf, "\n")) + if (!*buf) break; - buf[strlen(buf)-1] = '\0'; v = strchr(buf, '='); if (!v) @@@ -242,12 -295,13 +242,12 @@@ *v++ = '\0'; if (!strcmp(buf, "protocol")) - protocol = xstrdup(v); + protocol = utf8_to_utf16_dup(v); else if (!strcmp(buf, "host")) - host = xstrdup(v); + host = utf8_to_utf16_dup(v); else if (!strcmp(buf, "path")) - path = xstrdup(v); + path = utf8_to_utf16_dup(v); else if (!strcmp(buf, "username")) { - username = xstrdup(v); wusername = utf8_to_utf16_dup(v); } else if (!strcmp(buf, "password")) password = utf8_to_utf16_dup(v); @@@ -259,7 -313,7 +259,7 @@@ int main(int argc, char *argv[]) { const char *usage = - "Usage: git credential-wincred \n"; + "usage: git credential-wincred \n"; if (!argv[1]) die(usage); @@@ -276,20 -330,22 +276,20 @@@ return 0; /* prepare 'target', the unique key for the credential */ - strncat(target_buf, "git:", sizeof(target_buf)); - strncat(target_buf, protocol, sizeof(target_buf)); - strncat(target_buf, "://", sizeof(target_buf)); - if (username) { - strncat(target_buf, username, sizeof(target_buf)); - strncat(target_buf, "@", sizeof(target_buf)); + wcscpy(target, L"git:"); + wcsncat(target, protocol, ARRAY_SIZE(target)); + wcsncat(target, L"://", ARRAY_SIZE(target)); + if (wusername) { + wcsncat(target, wusername, ARRAY_SIZE(target)); + wcsncat(target, L"@", ARRAY_SIZE(target)); } if (host) - strncat(target_buf, host, sizeof(target_buf)); + wcsncat(target, host, ARRAY_SIZE(target)); if (path) { - strncat(target_buf, "/", sizeof(target_buf)); - strncat(target_buf, path, sizeof(target_buf)); + wcsncat(target, L"/", ARRAY_SIZE(target)); + wcsncat(target, path, ARRAY_SIZE(target)); } - target = utf8_to_utf16_dup(target_buf); - if (!strcmp(argv[1], "get")) get_credential(); else if (!strcmp(argv[1], "store"))