зеркало из https://github.com/microsoft/git.git
Merge /pub/scm/git/git to recover lost side branch
Sorry for the mistake of rewinding something already pushed out.
This recovers the side branch lost by that mistake, specifically
ea5a65a599
commit.
Signed-off-by: Junio C Hamano <junio@hera.kernel.org>
This commit is contained in:
Коммит
bfadbeddd1
|
@ -8,26 +8,17 @@ git-clone-pack - Clones a repository by receiving packed objects.
|
|||
|
||||
SYNOPSIS
|
||||
--------
|
||||
'git-clone-pack' [-q] [--keep] [--exec=<git-upload-pack>] [<host>:]<directory> [<head>...]
|
||||
'git-clone-pack' [--exec=<git-upload-pack>] [<host>:]<directory> [<head>...]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
Clones a repository into the current repository by invoking
|
||||
'git-upload-pack', possibly on the remote host via ssh, in
|
||||
the named repository, and invoking 'git-unpack-objects' locally
|
||||
to receive the pack.
|
||||
the named repository, and stores the sent pack in the local
|
||||
repository.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
-q::
|
||||
Pass '-q' flag to 'git-unpack-objects'; this makes the
|
||||
cloning process less verbose.
|
||||
|
||||
--keep::
|
||||
Do not invoke 'git-unpack-objects' on received data, but
|
||||
create a single packfile out of it instead, and store it
|
||||
in the object database.
|
||||
|
||||
--exec=<git-upload-pack>::
|
||||
Use this to specify the path to 'git-upload-pack' on the
|
||||
remote side, if it is not found on your $PATH.
|
||||
|
|
|
@ -25,6 +25,11 @@ OPTIONS
|
|||
-------
|
||||
include::pull-fetch-param.txt[]
|
||||
|
||||
-a, \--append::
|
||||
Append ref names and object names of fetched refs to the
|
||||
existing contents of $GIT_DIR/FETCH_HEAD. Without this
|
||||
option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
|
||||
|
||||
-u, \--update-head-ok::
|
||||
By default 'git-fetch' refuses to update the head which
|
||||
corresponds to the current branch. This flag disables the
|
||||
|
|
|
@ -24,6 +24,10 @@ OPTIONS
|
|||
-------
|
||||
include::pull-fetch-param.txt[]
|
||||
|
||||
-a, \--append::
|
||||
Append ref names and object names of fetched refs to the
|
||||
existing contents of $GIT_DIR/FETCH_HEAD. Without this
|
||||
option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
|
||||
|
||||
Author
|
||||
------
|
||||
|
|
|
@ -21,6 +21,15 @@ OPTIONS
|
|||
-------
|
||||
include::pull-fetch-param.txt[]
|
||||
|
||||
\--all::
|
||||
Instead of naming each ref to push, specifies all refs
|
||||
to be pushed.
|
||||
|
||||
-f, \--force::
|
||||
Usually, the command refuses to update a local ref that is
|
||||
not an ancestor of the remote ref used to overwrite it.
|
||||
This flag disables the check. What this means is that the
|
||||
local repository can lose commits; use it with care.
|
||||
|
||||
Author
|
||||
------
|
||||
|
|
|
@ -75,13 +75,3 @@ Some short-cut notations are also supported.
|
|||
pushing. That is, do not store it locally if
|
||||
fetching, and update the same name if pushing.
|
||||
|
||||
-a, \--append::
|
||||
Append ref names and object names of fetched refs to the
|
||||
existing contents of $GIT_DIR/FETCH_HEAD. Without this
|
||||
option old data in $GIT_DIR/FETCH_HEAD will be overwritten.
|
||||
|
||||
-f, \--force::
|
||||
Usually, the command refuses to update a local ref that is
|
||||
not an ancestor of the remote ref used to overwrite it.
|
||||
This flag disables the check. What this means is that the
|
||||
local repository can lose commits; use it with care.
|
||||
|
|
72
clone-pack.c
72
clone-pack.c
|
@ -3,10 +3,8 @@
|
|||
#include "pkt-line.h"
|
||||
#include <sys/wait.h>
|
||||
|
||||
static int quiet;
|
||||
static int keep_pack;
|
||||
static const char clone_pack_usage[] =
|
||||
"git-clone-pack [-q] [--keep] [--exec=<git-upload-pack>] [<host>:]<directory> [<heads>]*";
|
||||
"git-clone-pack [--exec=<git-upload-pack>] [<host>:]<directory> [<heads>]*";
|
||||
static const char *exec = "git-upload-pack";
|
||||
|
||||
static void clone_handshake(int fd[2], struct ref *ref)
|
||||
|
@ -114,41 +112,6 @@ static void write_refs(struct ref *ref)
|
|||
free(head_path);
|
||||
}
|
||||
|
||||
static int clone_by_unpack(int fd[2])
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0)
|
||||
die("git-clone-pack: unable to fork off git-unpack-objects");
|
||||
if (!pid) {
|
||||
dup2(fd[0], 0);
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
execlp("git-unpack-objects", "git-unpack-objects",
|
||||
quiet ? "-q" : NULL, NULL);
|
||||
die("git-unpack-objects exec failed");
|
||||
}
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
while (waitpid(pid, &status, 0) < 0) {
|
||||
if (errno != EINTR)
|
||||
die("waiting for git-unpack-objects: %s", strerror(errno));
|
||||
}
|
||||
if (WIFEXITED(status)) {
|
||||
int code = WEXITSTATUS(status);
|
||||
if (code)
|
||||
die("git-unpack-objects died with error code %d", code);
|
||||
return 0;
|
||||
}
|
||||
if (WIFSIGNALED(status)) {
|
||||
int sig = WTERMSIG(status);
|
||||
die("git-unpack-objects died of signal %d", sig);
|
||||
}
|
||||
die("Sherlock Holmes! git-unpack-objects died of unnatural causes %d!", status);
|
||||
}
|
||||
|
||||
static int finish_pack(const char *pack_tmp_name)
|
||||
{
|
||||
int pipe_fd[2];
|
||||
|
@ -294,35 +257,13 @@ static int clone_pack(int fd[2], int nr_match, char **match)
|
|||
}
|
||||
clone_handshake(fd, refs);
|
||||
|
||||
if (keep_pack)
|
||||
status = clone_without_unpack(fd);
|
||||
else
|
||||
status = clone_by_unpack(fd);
|
||||
status = clone_without_unpack(fd);
|
||||
|
||||
if (!status)
|
||||
write_refs(refs);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int clone_options(const char *var, const char *value)
|
||||
{
|
||||
if (!strcmp("clone.keeppack", var)) {
|
||||
keep_pack = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("clone.quiet", var)) {
|
||||
quiet = git_config_bool(var, value);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Put other local option parsing for this program
|
||||
* here ...
|
||||
*/
|
||||
|
||||
/* Fall back on the default ones */
|
||||
return git_default_config(var, value);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, ret, nr_heads;
|
||||
|
@ -330,25 +271,20 @@ int main(int argc, char **argv)
|
|||
int fd[2];
|
||||
pid_t pid;
|
||||
|
||||
git_config(clone_options);
|
||||
nr_heads = 0;
|
||||
heads = NULL;
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
|
||||
if (*arg == '-') {
|
||||
if (!strcmp("-q", arg)) {
|
||||
quiet = 1;
|
||||
if (!strcmp("-q", arg))
|
||||
continue;
|
||||
}
|
||||
if (!strncmp("--exec=", arg, 7)) {
|
||||
exec = arg + 7;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp("--keep", arg)) {
|
||||
keep_pack = 1;
|
||||
if (!strcmp("--keep", arg))
|
||||
continue;
|
||||
}
|
||||
usage(clone_pack_usage);
|
||||
}
|
||||
dest = arg;
|
||||
|
|
21
daemon.c
21
daemon.c
|
@ -13,7 +13,9 @@
|
|||
static int log_syslog;
|
||||
static int verbose;
|
||||
|
||||
static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all] [directory...]";
|
||||
static const char daemon_usage[] =
|
||||
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
|
||||
" [--timeout=n] [--init-timeout=n] [directory...]";
|
||||
|
||||
/* List of acceptable pathname prefixes */
|
||||
static char **ok_paths = NULL;
|
||||
|
@ -21,6 +23,9 @@ static char **ok_paths = NULL;
|
|||
/* If this is set, git-daemon-export-ok is not required */
|
||||
static int export_all_trees = 0;
|
||||
|
||||
/* Timeout, and initial timeout */
|
||||
static unsigned int timeout = 0;
|
||||
static unsigned int init_timeout = 0;
|
||||
|
||||
static void logreport(int priority, const char *err, va_list params)
|
||||
{
|
||||
|
@ -170,6 +175,8 @@ static int upload(char *dir)
|
|||
/* Enough for the longest path above including final null */
|
||||
int buflen = strlen(dir)+10;
|
||||
char *dirbuf = xmalloc(buflen);
|
||||
/* Timeout as string */
|
||||
char timeout_buf[64];
|
||||
|
||||
loginfo("Request for '%s'", dir);
|
||||
|
||||
|
@ -190,8 +197,10 @@ static int upload(char *dir)
|
|||
*/
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
|
||||
|
||||
/* git-upload-pack only ever reads stuff, so this is safe */
|
||||
execlp("git-upload-pack", "git-upload-pack", ".", NULL);
|
||||
execlp("git-upload-pack", "git-upload-pack", "--strict", timeout_buf, ".", NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -200,7 +209,9 @@ static int execute(void)
|
|||
static char line[1000];
|
||||
int len;
|
||||
|
||||
alarm(init_timeout ? init_timeout : timeout);
|
||||
len = packet_read_line(0, line, sizeof(line));
|
||||
alarm(0);
|
||||
|
||||
if (len && line[len-1] == '\n')
|
||||
line[--len] = 0;
|
||||
|
@ -598,6 +609,12 @@ int main(int argc, char **argv)
|
|||
export_all_trees = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--timeout=", 10)) {
|
||||
timeout = atoi(arg+10);
|
||||
}
|
||||
if (!strncmp(arg, "--init-timeout=", 10)) {
|
||||
init_timeout = atoi(arg+15);
|
||||
}
|
||||
if (!strcmp(arg, "--")) {
|
||||
ok_paths = &argv[i+1];
|
||||
break;
|
||||
|
|
57
fetch-pack.c
57
fetch-pack.c
|
@ -12,31 +12,66 @@ static const char fetch_pack_usage[] =
|
|||
"git-fetch-pack [-q] [-v] [--exec=upload-pack] [host:]directory <refs>...";
|
||||
static const char *exec = "git-upload-pack";
|
||||
|
||||
#define COMPLETE (1U << 0)
|
||||
|
||||
static int find_common(int fd[2], unsigned char *result_sha1,
|
||||
struct ref *refs)
|
||||
{
|
||||
int fetching;
|
||||
static char line[1000];
|
||||
int count = 0, flushes = 0, retval;
|
||||
static char rev_command[1024];
|
||||
int count = 0, flushes = 0, retval, rev_command_len;
|
||||
FILE *revs;
|
||||
|
||||
revs = popen("git-rev-list $(git-rev-parse --all)", "r");
|
||||
if (!revs)
|
||||
die("unable to run 'git-rev-list'");
|
||||
|
||||
strcpy(rev_command, "git-rev-list $(git-rev-parse --all)");
|
||||
rev_command_len = strlen(rev_command);
|
||||
fetching = 0;
|
||||
for ( ; refs ; refs = refs->next) {
|
||||
unsigned char *remote = refs->old_sha1;
|
||||
unsigned char *local = refs->new_sha1;
|
||||
struct object *o;
|
||||
|
||||
if (!memcmp(remote, local, 20))
|
||||
/*
|
||||
* If that object is complete (i.e. it is an ancestor of a
|
||||
* local ref), we tell them we have it but do not have to
|
||||
* tell them about its ancestors, which they already know
|
||||
* about.
|
||||
*
|
||||
* We use lookup_object here because we are only
|
||||
* interested in the case we *know* the object is
|
||||
* reachable and we have already scanned it.
|
||||
*/
|
||||
if (((o = lookup_object(remote)) != NULL) &&
|
||||
(o->flags & COMPLETE)) {
|
||||
struct commit_list *p;
|
||||
struct commit *commit =
|
||||
(struct commit *) (o = deref_tag(o));
|
||||
if (!o)
|
||||
goto repair;
|
||||
if (o->type != commit_type)
|
||||
continue;
|
||||
p = commit->parents;
|
||||
while (p &&
|
||||
rev_command_len + 44 < sizeof(rev_command)) {
|
||||
snprintf(rev_command + rev_command_len, 44,
|
||||
" ^%s",
|
||||
sha1_to_hex(p->item->object.sha1));
|
||||
rev_command_len += 43;
|
||||
p = p->next;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
repair:
|
||||
packet_write(fd[1], "want %s\n", sha1_to_hex(remote));
|
||||
fetching++;
|
||||
}
|
||||
packet_flush(fd[1]);
|
||||
if (!fetching)
|
||||
return 1;
|
||||
|
||||
revs = popen(rev_command, "r");
|
||||
if (!revs)
|
||||
die("unable to run 'git-rev-list'");
|
||||
|
||||
flushes = 1;
|
||||
retval = -1;
|
||||
while (fgets(line, sizeof(line), revs) != NULL) {
|
||||
|
@ -81,7 +116,6 @@ static int find_common(int fd[2], unsigned char *result_sha1,
|
|||
return retval;
|
||||
}
|
||||
|
||||
#define COMPLETE (1U << 0)
|
||||
static struct commit_list *complete = NULL;
|
||||
|
||||
static int mark_complete(const char *path, const unsigned char *sha1)
|
||||
|
@ -89,10 +123,13 @@ static int mark_complete(const char *path, const unsigned char *sha1)
|
|||
struct object *o = parse_object(sha1);
|
||||
|
||||
while (o && o->type == tag_type) {
|
||||
struct tag *t = (struct tag *) o;
|
||||
if (!t->tagged)
|
||||
break; /* broken repository */
|
||||
o->flags |= COMPLETE;
|
||||
o = parse_object(((struct tag *)o)->tagged->sha1);
|
||||
o = parse_object(t->tagged->sha1);
|
||||
}
|
||||
if (o->type == commit_type) {
|
||||
if (o && o->type == commit_type) {
|
||||
struct commit *commit = (struct commit *)o;
|
||||
commit->object.flags |= COMPLETE;
|
||||
insert_by_date(commit, &complete);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
. git-sh-setup
|
||||
|
||||
echo $(find "$GIT_DIR/objects"/?? -type f -print | wc -l) objects, \
|
||||
echo $(find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null | wc -l) objects, \
|
||||
$({
|
||||
echo 0
|
||||
# "no-such" is to help Darwin folks by not using xargs -r.
|
||||
|
|
29
http-fetch.c
29
http-fetch.c
|
@ -100,6 +100,8 @@ static char *ssl_key = NULL;
|
|||
static char *ssl_capath = NULL;
|
||||
#endif
|
||||
static char *ssl_cainfo = NULL;
|
||||
static long curl_low_speed_limit = -1;
|
||||
static long curl_low_speed_time = -1;
|
||||
|
||||
struct buffer
|
||||
{
|
||||
|
@ -158,6 +160,17 @@ static int http_options(const char *var, const char *value)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!strcmp("http.lowspeedlimit", var)) {
|
||||
if (curl_low_speed_limit == -1)
|
||||
curl_low_speed_limit = (long)git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
if (!strcmp("http.lowspeedtime", var)) {
|
||||
if (curl_low_speed_time == -1)
|
||||
curl_low_speed_time = (long)git_config_int(var, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fall back on the default ones */
|
||||
return git_default_config(var, value);
|
||||
}
|
||||
|
@ -246,6 +259,13 @@ static CURL* get_curl_handle(void)
|
|||
curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo);
|
||||
curl_easy_setopt(result, CURLOPT_FAILONERROR, 1);
|
||||
|
||||
if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) {
|
||||
curl_easy_setopt(result, CURLOPT_LOW_SPEED_LIMIT,
|
||||
curl_low_speed_limit);
|
||||
curl_easy_setopt(result, CURLOPT_LOW_SPEED_TIME,
|
||||
curl_low_speed_time);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1177,6 +1197,8 @@ int main(int argc, char **argv)
|
|||
char *url;
|
||||
int arg = 1;
|
||||
struct active_request_slot *slot;
|
||||
char *low_speed_limit;
|
||||
char *low_speed_time;
|
||||
|
||||
while (arg < argc && argv[arg][0] == '-') {
|
||||
if (argv[arg][1] == 't') {
|
||||
|
@ -1232,6 +1254,13 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
ssl_cainfo = getenv("GIT_SSL_CAINFO");
|
||||
|
||||
low_speed_limit = getenv("GIT_HTTP_LOW_SPEED_LIMIT");
|
||||
if (low_speed_limit != NULL)
|
||||
curl_low_speed_limit = strtol(low_speed_limit, NULL, 10);
|
||||
low_speed_time = getenv("GIT_HTTP_LOW_SPEED_TIME");
|
||||
if (low_speed_time != NULL)
|
||||
curl_low_speed_time = strtol(low_speed_time, NULL, 10);
|
||||
|
||||
git_config(http_options);
|
||||
|
||||
if (curl_ssl_verify == -1)
|
||||
|
|
|
@ -323,6 +323,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
|
|||
return -1;
|
||||
if (!type_string) {
|
||||
o = deref_tag(o);
|
||||
if (!o || (!o->parsed && !parse_object(o->sha1)))
|
||||
return -1;
|
||||
memcpy(sha1, o->sha1, 20);
|
||||
}
|
||||
else {
|
||||
|
@ -332,7 +334,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)
|
|||
*/
|
||||
|
||||
while (1) {
|
||||
if (!o)
|
||||
if (!o || (!o->parsed && !parse_object(o->sha1)))
|
||||
return -1;
|
||||
if (o->type == type_string) {
|
||||
memcpy(sha1, o->sha1, 20);
|
||||
|
|
|
@ -4,13 +4,19 @@
|
|||
#include "tag.h"
|
||||
#include "object.h"
|
||||
|
||||
static const char upload_pack_usage[] = "git-upload-pack <dir>";
|
||||
static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
|
||||
|
||||
#define MAX_HAS (16)
|
||||
#define MAX_NEEDS (256)
|
||||
static int nr_has = 0, nr_needs = 0;
|
||||
static unsigned char has_sha1[MAX_HAS][20];
|
||||
static unsigned char needs_sha1[MAX_NEEDS][20];
|
||||
static unsigned int timeout = 0;
|
||||
|
||||
static void reset_timeout(void)
|
||||
{
|
||||
alarm(timeout);
|
||||
}
|
||||
|
||||
static int strip(char *line, int len)
|
||||
{
|
||||
|
@ -100,6 +106,7 @@ static int get_common_commits(void)
|
|||
|
||||
for(;;) {
|
||||
len = packet_read_line(0, line, sizeof(line));
|
||||
reset_timeout();
|
||||
|
||||
if (!len) {
|
||||
packet_write(1, "NAK\n");
|
||||
|
@ -122,6 +129,7 @@ static int get_common_commits(void)
|
|||
|
||||
for (;;) {
|
||||
len = packet_read_line(0, line, sizeof(line));
|
||||
reset_timeout();
|
||||
if (!len)
|
||||
continue;
|
||||
len = strip(line, len);
|
||||
|
@ -145,6 +153,7 @@ static int receive_needs(void)
|
|||
for (;;) {
|
||||
unsigned char dummy[20], *sha1_buf;
|
||||
len = packet_read_line(0, line, sizeof(line));
|
||||
reset_timeout();
|
||||
if (!len)
|
||||
return needs;
|
||||
|
||||
|
@ -179,6 +188,7 @@ static int send_ref(const char *refname, const unsigned char *sha1)
|
|||
|
||||
static int upload_pack(void)
|
||||
{
|
||||
reset_timeout();
|
||||
head_ref(send_ref);
|
||||
for_each_ref(send_ref);
|
||||
packet_flush(1);
|
||||
|
@ -193,18 +203,43 @@ static int upload_pack(void)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *dir;
|
||||
if (argc != 2)
|
||||
int i;
|
||||
int strict = 0;
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
char *arg = argv[i];
|
||||
|
||||
if (arg[0] != '-')
|
||||
break;
|
||||
if (!strcmp(arg, "--strict")) {
|
||||
strict = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strncmp(arg, "--timeout=", 10)) {
|
||||
timeout = atoi(arg+10);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--")) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i != argc-1)
|
||||
usage(upload_pack_usage);
|
||||
dir = argv[1];
|
||||
dir = argv[i];
|
||||
|
||||
/* chdir to the directory. If that fails, try appending ".git" */
|
||||
if (chdir(dir) < 0) {
|
||||
if (chdir(mkpath("%s.git", dir)) < 0)
|
||||
if (strict || chdir(mkpath("%s.git", dir)) < 0)
|
||||
die("git-upload-pack unable to chdir to %s", dir);
|
||||
}
|
||||
chdir(".git");
|
||||
if (!strict)
|
||||
chdir(".git");
|
||||
|
||||
if (access("objects", X_OK) || access("refs", X_OK))
|
||||
die("git-upload-pack: %s doesn't seem to be a git archive", dir);
|
||||
|
||||
putenv("GIT_DIR=.");
|
||||
upload_pack();
|
||||
return 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче