Browse Source
This is not 1.0rc4 yet, but to push the recent fixes out. Signed-off-by: Junio C Hamano <junkio@cox.net>maint v0.99.9k
Junio C Hamano
19 years ago
77 changed files with 2856 additions and 1804 deletions
@ -0,0 +1,170 @@ |
|||||||
|
git-repo-config(1) |
||||||
|
================== |
||||||
|
|
||||||
|
NAME |
||||||
|
---- |
||||||
|
git-repo-config - Get and set options in .git/config. |
||||||
|
|
||||||
|
|
||||||
|
SYNOPSIS |
||||||
|
-------- |
||||||
|
'git-repo-config' name [value [value_regex]] |
||||||
|
'git-repo-config' --replace-all name [value [value_regex]] |
||||||
|
'git-repo-config' --get name [value_regex] |
||||||
|
'git-repo-config' --get-all name [value_regex] |
||||||
|
'git-repo-config' --unset name [value_regex] |
||||||
|
'git-repo-config' --unset-all name [value_regex] |
||||||
|
|
||||||
|
DESCRIPTION |
||||||
|
----------- |
||||||
|
You can query/set/replace/unset options with this command. The name is |
||||||
|
actually the section and the key separated by a dot, and the value will be |
||||||
|
escaped. |
||||||
|
|
||||||
|
If you want to set/unset an option which can occor on multiple lines, you |
||||||
|
should provide a POSIX regex for the value. If you want to handle the lines |
||||||
|
*not* matching the regex, just prepend a single exlamation mark in front |
||||||
|
(see EXAMPLES). |
||||||
|
|
||||||
|
This command will fail if |
||||||
|
|
||||||
|
. .git/config is invalid, |
||||||
|
. .git/config can not be written to, |
||||||
|
. no section was provided, |
||||||
|
. the section or key is invalid, |
||||||
|
. you try to unset an option which does not exist, or |
||||||
|
. you try to unset/set an option for which multiple lines match. |
||||||
|
|
||||||
|
|
||||||
|
OPTIONS |
||||||
|
------- |
||||||
|
|
||||||
|
--replace-all:: |
||||||
|
Default behaviour is to replace at most one line. This replaces |
||||||
|
all lines matching the key (and optionally the value_regex) |
||||||
|
|
||||||
|
--get:: |
||||||
|
Get the value for a given key (optionally filtered by a regex |
||||||
|
matching the value). |
||||||
|
|
||||||
|
--get-all:: |
||||||
|
Like get, but does not fail if the number of values for the key |
||||||
|
is not exactly one. |
||||||
|
|
||||||
|
--unset:: |
||||||
|
Remove the line matching the key from .git/config. |
||||||
|
|
||||||
|
--unset-all:: |
||||||
|
Remove all matching lines from .git/config. |
||||||
|
|
||||||
|
|
||||||
|
EXAMPLE |
||||||
|
------- |
||||||
|
|
||||||
|
Given a .git/config like this: |
||||||
|
|
||||||
|
# |
||||||
|
# This is the config file, and |
||||||
|
# a '#' or ';' character indicates |
||||||
|
# a comment |
||||||
|
# |
||||||
|
|
||||||
|
; core variables |
||||||
|
[core] |
||||||
|
; Don't trust file modes |
||||||
|
filemode = false |
||||||
|
|
||||||
|
; Our diff algorithm |
||||||
|
[diff] |
||||||
|
external = "/usr/local/bin/gnu-diff -u" |
||||||
|
renames = true |
||||||
|
|
||||||
|
; Proxy settings |
||||||
|
[proxy] |
||||||
|
command="ssh" for "ssh://kernel.org/" |
||||||
|
command="proxy-command" for kernel.org |
||||||
|
command="myprotocol-command" for "my://" |
||||||
|
command=default-proxy ; for all the rest |
||||||
|
|
||||||
|
you can set the filemode to true with |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config core.filemode true |
||||||
|
------------ |
||||||
|
|
||||||
|
The hypothetic proxy command entries actually have a postfix to discern |
||||||
|
to what URL they apply. Here is how to change the entry for kernel.org |
||||||
|
to "ssh". |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config proxy.command '"ssh" for kernel.org' 'for kernel.org$' |
||||||
|
------------ |
||||||
|
|
||||||
|
This makes sure that only the key/value pair for kernel.org is replaced. |
||||||
|
|
||||||
|
To delete the entry for renames, do |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config --unset diff.renames |
||||||
|
------------ |
||||||
|
|
||||||
|
If you want to delete an entry for a multivar (like proxy.command above), |
||||||
|
you have to provide a regex matching the value of exactly one line. |
||||||
|
|
||||||
|
To query the value for a given key, do |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config --get core.filemode |
||||||
|
------------ |
||||||
|
|
||||||
|
or |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config core.filemode |
||||||
|
------------ |
||||||
|
|
||||||
|
or, to query a multivar: |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config --get proxy.command "for kernel.org$" |
||||||
|
------------ |
||||||
|
|
||||||
|
If you want to know all the values for a multivar, do: |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config --get-all proxy.command |
||||||
|
------------ |
||||||
|
|
||||||
|
If you like to live dangerous, you can replace *all* proxy.commands by a |
||||||
|
new one with |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config --replace-all proxy.command ssh |
||||||
|
------------ |
||||||
|
|
||||||
|
However, if you really only want to replace the line for the default proxy, |
||||||
|
i.e. the one without a "for ..." postfix, do something like this: |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config proxy.command ssh '! for ' |
||||||
|
------------ |
||||||
|
|
||||||
|
To actually match only values with an exclamation mark, you have to |
||||||
|
|
||||||
|
------------ |
||||||
|
% git repo-config section.key value '[!]' |
||||||
|
------------ |
||||||
|
|
||||||
|
|
||||||
|
Author |
||||||
|
------ |
||||||
|
Written by Johannes Schindelin <Johannes.Schindelin@gmx.de> |
||||||
|
|
||||||
|
Documentation |
||||||
|
-------------- |
||||||
|
Documentation by Johannes Schindelin. |
||||||
|
|
||||||
|
GIT |
||||||
|
--- |
||||||
|
Part of the gitlink:git[7] suite |
||||||
|
|
@ -0,0 +1,105 @@ |
|||||||
|
From: Junio C Hamano <junkio@cox.net> |
||||||
|
Subject: control access to branches. |
||||||
|
Date: Thu, 17 Nov 2005 23:55:32 -0800 |
||||||
|
Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net> |
||||||
|
Abstract: An example hooks/update script is presented to |
||||||
|
implement repository maintenance policies, such as who can push |
||||||
|
into which branch and who can make a tag. |
||||||
|
|
||||||
|
When your developer runs git-push into the repository, |
||||||
|
git-receive-pack is run (either locally or over ssh) as that |
||||||
|
developer, so is hooks/update script. Quoting from the relevant |
||||||
|
section of the documentation: |
||||||
|
|
||||||
|
Before each ref is updated, if $GIT_DIR/hooks/update file exists |
||||||
|
and executable, it is called with three parameters: |
||||||
|
|
||||||
|
$GIT_DIR/hooks/update refname sha1-old sha1-new |
||||||
|
|
||||||
|
The refname parameter is relative to $GIT_DIR; e.g. for the |
||||||
|
master head this is "refs/heads/master". Two sha1 are the |
||||||
|
object names for the refname before and after the update. Note |
||||||
|
that the hook is called before the refname is updated, so either |
||||||
|
sha1-old is 0{40} (meaning there is no such ref yet), or it |
||||||
|
should match what is recorded in refname. |
||||||
|
|
||||||
|
So if your policy is (1) always require fast-forward push |
||||||
|
(i.e. never allow "git-push repo +branch:branch"), (2) you |
||||||
|
have a list of users allowed to update each branch, and (3) you |
||||||
|
do not let tags to be overwritten, then: |
||||||
|
|
||||||
|
#!/bin/sh |
||||||
|
# This is a sample hooks/update script, written by JC |
||||||
|
# in his e-mail buffer, so naturally it is not tested |
||||||
|
# but hopefully would convey the idea. |
||||||
|
|
||||||
|
umask 002 |
||||||
|
case "$1" in |
||||||
|
refs/tags/*) |
||||||
|
# No overwriting an existing tag |
||||||
|
if test -f "$GIT_DIR/$1" |
||||||
|
then |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
;; |
||||||
|
refs/heads/*) |
||||||
|
# No rebasing or rewinding |
||||||
|
if expr "$2" : '0*$' >/dev/null |
||||||
|
then |
||||||
|
# creating a new branch |
||||||
|
; |
||||||
|
else |
||||||
|
# updating -- make sure it is a fast forward |
||||||
|
mb=`git-merge-base "$2" "$3"` |
||||||
|
case "$mb,$2" in |
||||||
|
"$2,$mb") |
||||||
|
;; # fast forward -- happy |
||||||
|
*) |
||||||
|
exit 1 ;; # unhappy |
||||||
|
esac |
||||||
|
fi |
||||||
|
;; |
||||||
|
*) |
||||||
|
# No funny refs allowed |
||||||
|
exit 1 |
||||||
|
;; |
||||||
|
esac |
||||||
|
|
||||||
|
# Is the user allowed to update it? |
||||||
|
me=`id -u -n` ;# e.g. "junio" |
||||||
|
while read head_pattern users |
||||||
|
do |
||||||
|
if expr "$1" : "$head_pattern" >/dev/null |
||||||
|
then |
||||||
|
case " $users " in |
||||||
|
*" $me "*) |
||||||
|
exit 0 ;; # happy |
||||||
|
' * ') |
||||||
|
exit 0 ;; # anybody |
||||||
|
esac |
||||||
|
fi |
||||||
|
done |
||||||
|
exit 1 |
||||||
|
|
||||||
|
For the sake of simplicity, I assumed that you keep something |
||||||
|
like this in $GIT_DIR/info/allowed-pushers file: |
||||||
|
|
||||||
|
refs/heads/master junio |
||||||
|
refs/heads/cogito$ pasky |
||||||
|
refs/heads/bw/ linus |
||||||
|
refs/heads/tmp/ * |
||||||
|
refs/tags/v[0-9]* junio |
||||||
|
|
||||||
|
With this, Linus can push or create "bw/penguin" or "bw/zebra" |
||||||
|
or "bw/panda" branches, Pasky can do only "cogito", and I can do |
||||||
|
master branch and make versioned tags. And anybody can do |
||||||
|
tmp/blah branches. This assumes all the users are in a single |
||||||
|
group that can write into $GIT_DIR/ and underneath. |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,442 @@ |
|||||||
|
#include "http.h" |
||||||
|
|
||||||
|
int data_received; |
||||||
|
int active_requests = 0; |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
int max_requests = -1; |
||||||
|
CURLM *curlm; |
||||||
|
#endif |
||||||
|
#ifndef NO_CURL_EASY_DUPHANDLE |
||||||
|
CURL *curl_default; |
||||||
|
#endif |
||||||
|
char curl_errorstr[CURL_ERROR_SIZE]; |
||||||
|
|
||||||
|
int curl_ssl_verify = -1; |
||||||
|
char *ssl_cert = NULL; |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070902 |
||||||
|
char *ssl_key = NULL; |
||||||
|
#endif |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070908 |
||||||
|
char *ssl_capath = NULL; |
||||||
|
#endif |
||||||
|
char *ssl_cainfo = NULL; |
||||||
|
long curl_low_speed_limit = -1; |
||||||
|
long curl_low_speed_time = -1; |
||||||
|
|
||||||
|
struct curl_slist *pragma_header; |
||||||
|
struct curl_slist *no_range_header; |
||||||
|
|
||||||
|
struct active_request_slot *active_queue_head = NULL; |
||||||
|
|
||||||
|
size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, |
||||||
|
struct buffer *buffer) |
||||||
|
{ |
||||||
|
size_t size = eltsize * nmemb; |
||||||
|
if (size > buffer->size - buffer->posn) |
||||||
|
size = buffer->size - buffer->posn; |
||||||
|
memcpy(ptr, buffer->buffer + buffer->posn, size); |
||||||
|
buffer->posn += size; |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
size_t fwrite_buffer(const void *ptr, size_t eltsize, |
||||||
|
size_t nmemb, struct buffer *buffer) |
||||||
|
{ |
||||||
|
size_t size = eltsize * nmemb; |
||||||
|
if (size > buffer->size - buffer->posn) { |
||||||
|
buffer->size = buffer->size * 3 / 2; |
||||||
|
if (buffer->size < buffer->posn + size) |
||||||
|
buffer->size = buffer->posn + size; |
||||||
|
buffer->buffer = xrealloc(buffer->buffer, buffer->size); |
||||||
|
} |
||||||
|
memcpy(buffer->buffer + buffer->posn, ptr, size); |
||||||
|
buffer->posn += size; |
||||||
|
data_received++; |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
size_t fwrite_null(const void *ptr, size_t eltsize, |
||||||
|
size_t nmemb, struct buffer *buffer) |
||||||
|
{ |
||||||
|
data_received++; |
||||||
|
return eltsize * nmemb; |
||||||
|
} |
||||||
|
|
||||||
|
static void finish_active_slot(struct active_request_slot *slot); |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
static void process_curl_messages(void) |
||||||
|
{ |
||||||
|
int num_messages; |
||||||
|
struct active_request_slot *slot; |
||||||
|
CURLMsg *curl_message = curl_multi_info_read(curlm, &num_messages); |
||||||
|
|
||||||
|
while (curl_message != NULL) { |
||||||
|
if (curl_message->msg == CURLMSG_DONE) { |
||||||
|
int curl_result = curl_message->data.result; |
||||||
|
slot = active_queue_head; |
||||||
|
while (slot != NULL && |
||||||
|
slot->curl != curl_message->easy_handle) |
||||||
|
slot = slot->next; |
||||||
|
if (slot != NULL) { |
||||||
|
curl_multi_remove_handle(curlm, slot->curl); |
||||||
|
slot->curl_result = curl_result; |
||||||
|
finish_active_slot(slot); |
||||||
|
} else { |
||||||
|
fprintf(stderr, "Received DONE message for unknown request!\n"); |
||||||
|
} |
||||||
|
} else { |
||||||
|
fprintf(stderr, "Unknown CURL message received: %d\n", |
||||||
|
(int)curl_message->msg); |
||||||
|
} |
||||||
|
curl_message = curl_multi_info_read(curlm, &num_messages); |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
static int http_options(const char *var, const char *value) |
||||||
|
{ |
||||||
|
if (!strcmp("http.sslverify", var)) { |
||||||
|
if (curl_ssl_verify == -1) { |
||||||
|
curl_ssl_verify = git_config_bool(var, value); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (!strcmp("http.sslcert", var)) { |
||||||
|
if (ssl_cert == NULL) { |
||||||
|
ssl_cert = xmalloc(strlen(value)+1); |
||||||
|
strcpy(ssl_cert, value); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070902 |
||||||
|
if (!strcmp("http.sslkey", var)) { |
||||||
|
if (ssl_key == NULL) { |
||||||
|
ssl_key = xmalloc(strlen(value)+1); |
||||||
|
strcpy(ssl_key, value); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
#endif |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070908 |
||||||
|
if (!strcmp("http.sslcapath", var)) { |
||||||
|
if (ssl_capath == NULL) { |
||||||
|
ssl_capath = xmalloc(strlen(value)+1); |
||||||
|
strcpy(ssl_capath, value); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
#endif |
||||||
|
if (!strcmp("http.sslcainfo", var)) { |
||||||
|
if (ssl_cainfo == NULL) { |
||||||
|
ssl_cainfo = xmalloc(strlen(value)+1); |
||||||
|
strcpy(ssl_cainfo, value); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
if (!strcmp("http.maxrequests", var)) { |
||||||
|
if (max_requests == -1) |
||||||
|
max_requests = git_config_int(var, value); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
#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); |
||||||
|
} |
||||||
|
|
||||||
|
static CURL* get_curl_handle(void) |
||||||
|
{ |
||||||
|
CURL* result = curl_easy_init(); |
||||||
|
|
||||||
|
curl_easy_setopt(result, CURLOPT_SSL_VERIFYPEER, curl_ssl_verify); |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070907 |
||||||
|
curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); |
||||||
|
#endif |
||||||
|
|
||||||
|
if (ssl_cert != NULL) |
||||||
|
curl_easy_setopt(result, CURLOPT_SSLCERT, ssl_cert); |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070902 |
||||||
|
if (ssl_key != NULL) |
||||||
|
curl_easy_setopt(result, CURLOPT_SSLKEY, ssl_key); |
||||||
|
#endif |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070908 |
||||||
|
if (ssl_capath != NULL) |
||||||
|
curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath); |
||||||
|
#endif |
||||||
|
if (ssl_cainfo != NULL) |
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
void http_init(void) |
||||||
|
{ |
||||||
|
char *low_speed_limit; |
||||||
|
char *low_speed_time; |
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_ALL); |
||||||
|
|
||||||
|
pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache"); |
||||||
|
no_range_header = curl_slist_append(no_range_header, "Range:"); |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
{ |
||||||
|
char *http_max_requests = getenv("GIT_HTTP_MAX_REQUESTS"); |
||||||
|
if (http_max_requests != NULL) |
||||||
|
max_requests = atoi(http_max_requests); |
||||||
|
} |
||||||
|
|
||||||
|
curlm = curl_multi_init(); |
||||||
|
if (curlm == NULL) { |
||||||
|
fprintf(stderr, "Error creating curl multi handle.\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
if (getenv("GIT_SSL_NO_VERIFY")) |
||||||
|
curl_ssl_verify = 0; |
||||||
|
|
||||||
|
ssl_cert = getenv("GIT_SSL_CERT"); |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070902 |
||||||
|
ssl_key = getenv("GIT_SSL_KEY"); |
||||||
|
#endif |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070908 |
||||||
|
ssl_capath = getenv("GIT_SSL_CAPATH"); |
||||||
|
#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) |
||||||
|
curl_ssl_verify = 1; |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
if (max_requests < 1) |
||||||
|
max_requests = DEFAULT_MAX_REQUESTS; |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifndef NO_CURL_EASY_DUPHANDLE |
||||||
|
curl_default = get_curl_handle(); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
void http_cleanup(void) |
||||||
|
{ |
||||||
|
struct active_request_slot *slot = active_queue_head; |
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
char *wait_url; |
||||||
|
#endif |
||||||
|
|
||||||
|
while (slot != NULL) { |
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
if (slot->in_use) { |
||||||
|
curl_easy_getinfo(slot->curl, |
||||||
|
CURLINFO_EFFECTIVE_URL, |
||||||
|
&wait_url); |
||||||
|
fprintf(stderr, "Waiting for %s\n", wait_url); |
||||||
|
run_active_slot(slot); |
||||||
|
} |
||||||
|
#endif |
||||||
|
if (slot->curl != NULL) |
||||||
|
curl_easy_cleanup(slot->curl); |
||||||
|
slot = slot->next; |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef NO_CURL_EASY_DUPHANDLE |
||||||
|
curl_easy_cleanup(curl_default); |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
curl_multi_cleanup(curlm); |
||||||
|
#endif |
||||||
|
curl_global_cleanup(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
struct active_request_slot *get_active_slot(void) |
||||||
|
{ |
||||||
|
struct active_request_slot *slot = active_queue_head; |
||||||
|
struct active_request_slot *newslot; |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
int num_transfers; |
||||||
|
|
||||||
|
/* Wait for a slot to open up if the queue is full */ |
||||||
|
while (active_requests >= max_requests) { |
||||||
|
curl_multi_perform(curlm, &num_transfers); |
||||||
|
if (num_transfers < active_requests) { |
||||||
|
process_curl_messages(); |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
while (slot != NULL && slot->in_use) { |
||||||
|
slot = slot->next; |
||||||
|
} |
||||||
|
if (slot == NULL) { |
||||||
|
newslot = xmalloc(sizeof(*newslot)); |
||||||
|
newslot->curl = NULL; |
||||||
|
newslot->in_use = 0; |
||||||
|
newslot->next = NULL; |
||||||
|
|
||||||
|
slot = active_queue_head; |
||||||
|
if (slot == NULL) { |
||||||
|
active_queue_head = newslot; |
||||||
|
} else { |
||||||
|
while (slot->next != NULL) { |
||||||
|
slot = slot->next; |
||||||
|
} |
||||||
|
slot->next = newslot; |
||||||
|
} |
||||||
|
slot = newslot; |
||||||
|
} |
||||||
|
|
||||||
|
if (slot->curl == NULL) { |
||||||
|
#ifdef NO_CURL_EASY_DUPHANDLE |
||||||
|
slot->curl = get_curl_handle(); |
||||||
|
#else |
||||||
|
slot->curl = curl_easy_duphandle(curl_default); |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
active_requests++; |
||||||
|
slot->in_use = 1; |
||||||
|
slot->local = NULL; |
||||||
|
slot->callback_data = NULL; |
||||||
|
slot->callback_func = NULL; |
||||||
|
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, pragma_header); |
||||||
|
curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, no_range_header); |
||||||
|
curl_easy_setopt(slot->curl, CURLOPT_ERRORBUFFER, curl_errorstr); |
||||||
|
|
||||||
|
return slot; |
||||||
|
} |
||||||
|
|
||||||
|
int start_active_slot(struct active_request_slot *slot) |
||||||
|
{ |
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
CURLMcode curlm_result = curl_multi_add_handle(curlm, slot->curl); |
||||||
|
|
||||||
|
if (curlm_result != CURLM_OK && |
||||||
|
curlm_result != CURLM_CALL_MULTI_PERFORM) { |
||||||
|
active_requests--; |
||||||
|
slot->in_use = 0; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
#endif |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
void step_active_slots(void) |
||||||
|
{ |
||||||
|
int num_transfers; |
||||||
|
CURLMcode curlm_result; |
||||||
|
|
||||||
|
do { |
||||||
|
curlm_result = curl_multi_perform(curlm, &num_transfers); |
||||||
|
} while (curlm_result == CURLM_CALL_MULTI_PERFORM); |
||||||
|
if (num_transfers < active_requests) { |
||||||
|
process_curl_messages(); |
||||||
|
fill_active_slots(); |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
void run_active_slot(struct active_request_slot *slot) |
||||||
|
{ |
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
long last_pos = 0; |
||||||
|
long current_pos; |
||||||
|
fd_set readfds; |
||||||
|
fd_set writefds; |
||||||
|
fd_set excfds; |
||||||
|
int max_fd; |
||||||
|
struct timeval select_timeout; |
||||||
|
|
||||||
|
while (slot->in_use) { |
||||||
|
data_received = 0; |
||||||
|
step_active_slots(); |
||||||
|
|
||||||
|
if (!data_received && slot->local != NULL) { |
||||||
|
current_pos = ftell(slot->local); |
||||||
|
if (current_pos > last_pos) |
||||||
|
data_received++; |
||||||
|
last_pos = current_pos; |
||||||
|
} |
||||||
|
|
||||||
|
if (slot->in_use && !data_received) { |
||||||
|
max_fd = 0; |
||||||
|
FD_ZERO(&readfds); |
||||||
|
FD_ZERO(&writefds); |
||||||
|
FD_ZERO(&excfds); |
||||||
|
select_timeout.tv_sec = 0; |
||||||
|
select_timeout.tv_usec = 50000; |
||||||
|
select(max_fd, &readfds, &writefds, |
||||||
|
&excfds, &select_timeout); |
||||||
|
} |
||||||
|
} |
||||||
|
#else |
||||||
|
while (slot->in_use) { |
||||||
|
slot->curl_result = curl_easy_perform(slot->curl); |
||||||
|
finish_active_slot(slot); |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
static void finish_active_slot(struct active_request_slot *slot) |
||||||
|
{ |
||||||
|
active_requests--; |
||||||
|
slot->in_use = 0; |
||||||
|
curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE, &slot->http_code); |
||||||
|
|
||||||
|
/* Run callback if appropriate */ |
||||||
|
if (slot->callback_func != NULL) { |
||||||
|
slot->callback_func(slot->callback_data); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void finish_all_active_slots(void) |
||||||
|
{ |
||||||
|
struct active_request_slot *slot = active_queue_head; |
||||||
|
|
||||||
|
while (slot != NULL) |
||||||
|
if (slot->in_use) { |
||||||
|
run_active_slot(slot); |
||||||
|
slot = active_queue_head; |
||||||
|
} else { |
||||||
|
slot = slot->next; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
#ifndef HTTP_H |
||||||
|
#define HTTP_H |
||||||
|
|
||||||
|
#include "cache.h" |
||||||
|
|
||||||
|
#include <curl/curl.h> |
||||||
|
#include <curl/easy.h> |
||||||
|
|
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070908 |
||||||
|
#define USE_CURL_MULTI |
||||||
|
#define DEFAULT_MAX_REQUESTS 5 |
||||||
|
#endif |
||||||
|
|
||||||
|
#if LIBCURL_VERSION_NUM < 0x070704 |
||||||
|
#define curl_global_cleanup() do { /* nothing */ } while(0) |
||||||
|
#endif |
||||||
|
#if LIBCURL_VERSION_NUM < 0x070800 |
||||||
|
#define curl_global_init(a) do { /* nothing */ } while(0) |
||||||
|
#endif |
||||||
|
|
||||||
|
#if LIBCURL_VERSION_NUM < 0x070c04 |
||||||
|
#define NO_CURL_EASY_DUPHANDLE |
||||||
|
#endif |
||||||
|
|
||||||
|
struct active_request_slot |
||||||
|
{ |
||||||
|
CURL *curl; |
||||||
|
FILE *local; |
||||||
|
int in_use; |
||||||
|
CURLcode curl_result; |
||||||
|
long http_code; |
||||||
|
void *callback_data; |
||||||
|
void (*callback_func)(void *data); |
||||||
|
struct active_request_slot *next; |
||||||
|
}; |
||||||
|
|
||||||
|
struct buffer |
||||||
|
{ |
||||||
|
size_t posn; |
||||||
|
size_t size; |
||||||
|
void *buffer; |
||||||
|
}; |
||||||
|
|
||||||
|
/* Curl request read/write callbacks */ |
||||||
|
extern size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, |
||||||
|
struct buffer *buffer); |
||||||
|
extern size_t fwrite_buffer(const void *ptr, size_t eltsize, |
||||||
|
size_t nmemb, struct buffer *buffer); |
||||||
|
extern size_t fwrite_null(const void *ptr, size_t eltsize, |
||||||
|
size_t nmemb, struct buffer *buffer); |
||||||
|
|
||||||
|
/* Slot lifecycle functions */ |
||||||
|
extern struct active_request_slot *get_active_slot(void); |
||||||
|
extern int start_active_slot(struct active_request_slot *slot); |
||||||
|
extern void run_active_slot(struct active_request_slot *slot); |
||||||
|
extern void finish_all_active_slots(void); |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
extern void fill_active_slots(void); |
||||||
|
extern void step_active_slots(void); |
||||||
|
#endif |
||||||
|
|
||||||
|
extern void http_init(void); |
||||||
|
extern void http_cleanup(void); |
||||||
|
|
||||||
|
extern int data_received; |
||||||
|
extern int active_requests; |
||||||
|
|
||||||
|
#ifdef USE_CURL_MULTI |
||||||
|
extern int max_requests; |
||||||
|
extern CURLM *curlm; |
||||||
|
#endif |
||||||
|
#ifndef NO_CURL_EASY_DUPHANDLE |
||||||
|
extern CURL *curl_default; |
||||||
|
#endif |
||||||
|
extern char curl_errorstr[CURL_ERROR_SIZE]; |
||||||
|
|
||||||
|
extern int curl_ssl_verify; |
||||||
|
extern char *ssl_cert; |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070902 |
||||||
|
extern char *ssl_key; |
||||||
|
#endif |
||||||
|
#if LIBCURL_VERSION_NUM >= 0x070908 |
||||||
|
extern char *ssl_capath; |
||||||
|
#endif |
||||||
|
extern char *ssl_cainfo; |
||||||
|
extern long curl_low_speed_limit; |
||||||
|
extern long curl_low_speed_time; |
||||||
|
|
||||||
|
extern struct curl_slist *pragma_header; |
||||||
|
extern struct curl_slist *no_range_header; |
||||||
|
|
||||||
|
extern struct active_request_slot *active_queue_head; |
||||||
|
|
||||||
|
#endif /* HTTP_H */ |
@ -0,0 +1,116 @@ |
|||||||
|
#include "cache.h" |
||||||
|
#include <regex.h> |
||||||
|
|
||||||
|
static const char git_config_set_usage[] = |
||||||
|
"git-repo-config [--get | --get-all | --replace-all | --unset | --unset-all] name [value [value_regex]]"; |
||||||
|
|
||||||
|
static char* key = NULL; |
||||||
|
static char* value = NULL; |
||||||
|
static regex_t* regex = NULL; |
||||||
|
static int do_all = 0; |
||||||
|
static int do_not_match = 0; |
||||||
|
static int seen = 0; |
||||||
|
|
||||||
|
static int show_config(const char* key_, const char* value_) |
||||||
|
{ |
||||||
|
if (!strcmp(key_, key) && |
||||||
|
(regex == NULL || |
||||||
|
(do_not_match ^ |
||||||
|
!regexec(regex, value_, 0, NULL, 0)))) { |
||||||
|
if (do_all) { |
||||||
|
printf("%s\n", value_); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
if (seen > 0) { |
||||||
|
fprintf(stderr, "More than one value: %s\n", value); |
||||||
|
free(value); |
||||||
|
} |
||||||
|
value = strdup(value_); |
||||||
|
seen++; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int get_value(const char* key_, const char* regex_) |
||||||
|
{ |
||||||
|
int i; |
||||||
|
|
||||||
|
key = malloc(strlen(key_)+1); |
||||||
|
for (i = 0; key_[i]; i++) |
||||||
|
key[i] = tolower(key_[i]); |
||||||
|
key[i] = 0; |
||||||
|
|
||||||
|
if (regex_) { |
||||||
|
if (regex_[0] == '!') { |
||||||
|
do_not_match = 1; |
||||||
|
regex_++; |
||||||
|
} |
||||||
|
|
||||||
|
regex = (regex_t*)malloc(sizeof(regex_t)); |
||||||
|
if (regcomp(regex, regex_, REG_EXTENDED)) { |
||||||
|
fprintf(stderr, "Invalid pattern: %s\n", regex_); |
||||||
|
return -1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
i = git_config(show_config); |
||||||
|
if (value) { |
||||||
|
printf("%s\n", value); |
||||||
|
free(value); |
||||||
|
} |
||||||
|
free(key); |
||||||
|
if (regex) { |
||||||
|
regfree(regex); |
||||||
|
free(regex); |
||||||
|
} |
||||||
|
|
||||||
|
if (do_all) |
||||||
|
return 0; |
||||||
|
|
||||||
|
return seen == 1 ? 0 : 1; |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, const char **argv) |
||||||
|
{ |
||||||
|
setup_git_directory(); |
||||||
|
switch (argc) { |
||||||
|
case 2: |
||||||
|
return get_value(argv[1], NULL); |
||||||
|
case 3: |
||||||
|
if (!strcmp(argv[1], "--unset")) |
||||||
|
return git_config_set(argv[2], NULL); |
||||||
|
else if (!strcmp(argv[1], "--unset-all")) |
||||||
|
return git_config_set_multivar(argv[2], NULL, NULL, 1); |
||||||
|
else if (!strcmp(argv[1], "--get")) |
||||||
|
return get_value(argv[2], NULL); |
||||||
|
else if (!strcmp(argv[1], "--get-all")) { |
||||||
|
do_all = 1; |
||||||
|
return get_value(argv[2], NULL); |
||||||
|
} else |
||||||
|
|
||||||
|
return git_config_set(argv[1], argv[2]); |
||||||
|
case 4: |
||||||
|
if (!strcmp(argv[1], "--unset")) |
||||||
|
return git_config_set_multivar(argv[2], NULL, argv[3], 0); |
||||||
|
else if (!strcmp(argv[1], "--unset-all")) |
||||||
|
return git_config_set_multivar(argv[2], NULL, argv[3], 1); |
||||||
|
else if (!strcmp(argv[1], "--get")) |
||||||
|
return get_value(argv[2], argv[3]); |
||||||
|
else if (!strcmp(argv[1], "--get-all")) { |
||||||
|
do_all = 1; |
||||||
|
return get_value(argv[2], argv[3]); |
||||||
|
} else if (!strcmp(argv[1], "--replace-all")) |
||||||
|
|
||||||
|
return git_config_set_multivar(argv[2], argv[3], NULL, 1); |
||||||
|
else |
||||||
|
|
||||||
|
return git_config_set_multivar(argv[1], argv[2], argv[3], 0); |
||||||
|
case 5: |
||||||
|
if (!strcmp(argv[1], "--replace-all")) |
||||||
|
return git_config_set_multivar(argv[2], argv[3], argv[4], 1); |
||||||
|
case 1: |
||||||
|
default: |
||||||
|
usage(git_config_set_usage); |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,271 @@ |
|||||||
|
#!/bin/sh |
||||||
|
# |
||||||
|
# Copyright (c) 2005 Johannes Schindelin |
||||||
|
# |
||||||
|
|
||||||
|
test_description='Test git-repo-config in different settings' |
||||||
|
|
||||||
|
. ./test-lib.sh |
||||||
|
|
||||||
|
test -f .git/config && rm .git/config |
||||||
|
|
||||||
|
git-repo-config core.penguin "little blue" |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
# |
||||||
|
# This is the config file |
||||||
|
# |
||||||
|
|
||||||
|
[core] |
||||||
|
penguin = little blue |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'initial' 'cmp .git/config expect' |
||||||
|
|
||||||
|
git-repo-config Core.Movie BadPhysics |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
# |
||||||
|
# This is the config file |
||||||
|
# |
||||||
|
|
||||||
|
[core] |
||||||
|
penguin = little blue |
||||||
|
Movie = BadPhysics |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'mixed case' 'cmp .git/config expect' |
||||||
|
|
||||||
|
git-repo-config Cores.WhatEver Second |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
# |
||||||
|
# This is the config file |
||||||
|
# |
||||||
|
|
||||||
|
[core] |
||||||
|
penguin = little blue |
||||||
|
Movie = BadPhysics |
||||||
|
[Cores] |
||||||
|
WhatEver = Second |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'similar section' 'cmp .git/config expect' |
||||||
|
|
||||||
|
git-repo-config CORE.UPPERCASE true |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
# |
||||||
|
# This is the config file |
||||||
|
# |
||||||
|
|
||||||
|
[core] |
||||||
|
penguin = little blue |
||||||
|
Movie = BadPhysics |
||||||
|
UPPERCASE = true |
||||||
|
[Cores] |
||||||
|
WhatEver = Second |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'similar section' 'cmp .git/config expect' |
||||||
|
|
||||||
|
test_expect_success 'replace with non-match' \ |
||||||
|
'git-repo-config core.penguin kingpin !blue' |
||||||
|
|
||||||
|
test_expect_success 'replace with non-match (actually matching)' \ |
||||||
|
'git-repo-config core.penguin "very blue" !kingpin' |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
# |
||||||
|
# This is the config file |
||||||
|
# |
||||||
|
|
||||||
|
[core] |
||||||
|
penguin = very blue |
||||||
|
Movie = BadPhysics |
||||||
|
UPPERCASE = true |
||||||
|
penguin = kingpin |
||||||
|
[Cores] |
||||||
|
WhatEver = Second |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'non-match result' 'cmp .git/config expect' |
||||||
|
|
||||||
|
cat > .git/config << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
haha ="beta" # last silly comment |
||||||
|
haha = hello |
||||||
|
haha = bello |
||||||
|
[nextSection] noNewline = ouch |
||||||
|
EOF |
||||||
|
|
||||||
|
cp .git/config .git/config2 |
||||||
|
|
||||||
|
test_expect_success 'multiple unset' \ |
||||||
|
'git-repo-config --unset-all beta.haha' |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
[nextSection] noNewline = ouch |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'multiple unset is correct' 'cmp .git/config expect' |
||||||
|
|
||||||
|
mv .git/config2 .git/config |
||||||
|
|
||||||
|
test_expect_success '--replace-all' \ |
||||||
|
'git-repo-config --replace-all beta.haha gamma' |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
haha = gamma |
||||||
|
[nextSection] noNewline = ouch |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'all replaced' 'cmp .git/config expect' |
||||||
|
|
||||||
|
git-repo-config beta.haha alpha |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
haha = alpha |
||||||
|
[nextSection] noNewline = ouch |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'really mean test' 'cmp .git/config expect' |
||||||
|
|
||||||
|
git-repo-config nextsection.nonewline wow |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
haha = alpha |
||||||
|
[nextSection] |
||||||
|
nonewline = wow |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'really really mean test' 'cmp .git/config expect' |
||||||
|
|
||||||
|
test_expect_success 'get value' 'test alpha = $(git-repo-config beta.haha)' |
||||||
|
git-repo-config --unset beta.haha |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
[nextSection] |
||||||
|
nonewline = wow |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'unset' 'cmp .git/config expect' |
||||||
|
|
||||||
|
git-repo-config nextsection.NoNewLine "wow2 for me" "for me$" |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
[nextSection] |
||||||
|
nonewline = wow |
||||||
|
NoNewLine = wow2 for me |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'multivar' 'cmp .git/config expect' |
||||||
|
|
||||||
|
test_expect_success 'non-match' \ |
||||||
|
'git-repo-config --get nextsection.nonewline !for' |
||||||
|
|
||||||
|
test_expect_success 'non-match value' \ |
||||||
|
'test wow = $(git-repo-config --get nextsection.nonewline !for)' |
||||||
|
|
||||||
|
test_expect_failure 'ambiguous get' \ |
||||||
|
'git-repo-config --get nextsection.nonewline' |
||||||
|
|
||||||
|
test_expect_success 'get multivar' \ |
||||||
|
'git-repo-config --get-all nextsection.nonewline' |
||||||
|
|
||||||
|
git-repo-config nextsection.nonewline "wow3" "wow$" |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
[nextSection] |
||||||
|
nonewline = wow3 |
||||||
|
NoNewLine = wow2 for me |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'multivar replace' 'cmp .git/config expect' |
||||||
|
|
||||||
|
test_expect_failure 'ambiguous value' 'git-repo-config nextsection.nonewline' |
||||||
|
|
||||||
|
test_expect_failure 'ambiguous unset' \ |
||||||
|
'git-repo-config --unset nextsection.nonewline' |
||||||
|
|
||||||
|
test_expect_failure 'invalid unset' \ |
||||||
|
'git-repo-config --unset somesection.nonewline' |
||||||
|
|
||||||
|
git-repo-config --unset nextsection.nonewline "wow3$" |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
[nextSection] |
||||||
|
NoNewLine = wow2 for me |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'multivar unset' 'cmp .git/config expect' |
||||||
|
|
||||||
|
test_expect_failure 'invalid key' 'git-repo-config inval.2key blabla' |
||||||
|
|
||||||
|
test_expect_success 'correct key' 'git-repo-config 123456.a123 987' |
||||||
|
|
||||||
|
test_expect_success 'hierarchical section' \ |
||||||
|
'git-repo-config 1.2.3.alpha beta' |
||||||
|
|
||||||
|
cat > expect << EOF |
||||||
|
[beta] ; silly comment # another comment |
||||||
|
noIndent= sillyValue ; 'nother silly comment |
||||||
|
|
||||||
|
# empty line |
||||||
|
; comment |
||||||
|
[nextSection] |
||||||
|
NoNewLine = wow2 for me |
||||||
|
[123456] |
||||||
|
a123 = 987 |
||||||
|
[1.2.3] |
||||||
|
alpha = beta |
||||||
|
EOF |
||||||
|
|
||||||
|
test_expect_success 'hierarchical section value' 'cmp .git/config expect' |
||||||
|
|
||||||
|
test_done |
||||||
|
|
Loading…
Reference in new issue