2005-11-02 22:19:24 +03:00
# include "cache.h"
# include "commit.h"
# include "tag.h"
# include "blob.h"
2005-11-18 22:02:58 +03:00
# include "http.h"
2006-03-08 03:13:20 +03:00
# include "refs.h"
2006-04-11 05:14:54 +04:00
# include "diff.h"
2006-03-08 03:13:20 +03:00
# include "revision.h"
2006-03-20 21:31:06 +03:00
# include "exec_cmd.h"
2007-05-12 19:45:59 +04:00
# include "remote.h"
2008-06-07 22:39:20 +04:00
# include "list-objects.h"
chain kill signals for cleanup functions
If a piece of code wanted to do some cleanup before exiting
(e.g., cleaning up a lockfile or a tempfile), our usual
strategy was to install a signal handler that did something
like this:
do_cleanup(); /* actual work */
signal(signo, SIG_DFL); /* restore previous behavior */
raise(signo); /* deliver signal, killing ourselves */
For a single handler, this works fine. However, if we want
to clean up two _different_ things, we run into a problem.
The most recently installed handler will run, but when it
removes itself as a handler, it doesn't put back the first
handler.
This patch introduces sigchain, a tiny library for handling
a stack of signal handlers. You sigchain_push each handler,
and use sigchain_pop to restore whoever was before you in
the stack.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-22 09:02:35 +03:00
# include "sigchain.h"
2015-09-25 00:07:56 +03:00
# include "argv-array.h"
2005-11-18 22:02:58 +03:00
2013-02-12 02:03:45 +04:00
# ifdef EXPAT_NEEDS_XMLPARSE_H
# include <xmlparse.h>
# else
2005-11-07 00:07:45 +03:00
# include <expat.h>
2013-02-12 02:03:45 +04:00
# endif
2005-11-02 22:19:24 +03:00
static const char http_push_usage [ ] =
2008-07-13 17:36:15 +04:00
" git http-push [--all] [--dry-run] [--force] [--verbose] <remote> [<head>...] \n " ;
2005-11-02 22:19:24 +03:00
2005-11-07 21:23:11 +03:00
# ifndef XML_STATUS_OK
enum XML_Status {
XML_STATUS_OK = 1 ,
XML_STATUS_ERROR = 0
} ;
# define XML_STATUS_OK 1
# define XML_STATUS_ERROR 0
# endif
2006-03-11 07:18:18 +03:00
# define PREV_BUF_SIZE 4096
2005-11-02 22:19:24 +03:00
2005-11-18 22:03:18 +03:00
/* DAV methods */
2005-11-02 22:19:24 +03:00
# define DAV_LOCK "LOCK"
# define DAV_MKCOL "MKCOL"
# define DAV_MOVE "MOVE"
# define DAV_PROPFIND "PROPFIND"
# define DAV_PUT "PUT"
# define DAV_UNLOCK "UNLOCK"
2006-03-20 21:31:06 +03:00
# define DAV_DELETE "DELETE"
2005-11-18 22:03:18 +03:00
/* DAV lock flags */
# define DAV_PROP_LOCKWR (1u << 0)
# define DAV_PROP_LOCKEX (1u << 1)
# define DAV_LOCK_OK (1u << 2)
/* DAV XML properties */
# define DAV_CTX_LOCKENTRY ".multistatus.response.propstat.prop.supportedlock.lockentry"
# define DAV_CTX_LOCKTYPE_WRITE ".multistatus.response.propstat.prop.supportedlock.lockentry.locktype.write"
# define DAV_CTX_LOCKTYPE_EXCLUSIVE ".multistatus.response.propstat.prop.supportedlock.lockentry.lockscope.exclusive"
# define DAV_ACTIVELOCK_OWNER ".prop.lockdiscovery.activelock.owner.href"
# define DAV_ACTIVELOCK_TIMEOUT ".prop.lockdiscovery.activelock.timeout"
# define DAV_ACTIVELOCK_TOKEN ".prop.lockdiscovery.activelock.locktoken.href"
2006-03-08 03:13:20 +03:00
# define DAV_PROPFIND_RESP ".multistatus.response"
# define DAV_PROPFIND_NAME ".multistatus.response.href"
# define DAV_PROPFIND_COLLECTION ".multistatus.response.propstat.prop.resourcetype.collection"
2005-11-18 22:03:18 +03:00
/* DAV request body templates */
2006-03-08 03:13:20 +03:00
# define PROPFIND_SUPPORTEDLOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:prop xmlns:R=\"%s\">\n<D:supportedlock / >\n< / D:prop>\n< / D:propfind>"
# define PROPFIND_ALL_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:propfind xmlns:D=\"DAV:\">\n<D:allprop / >\n< / D:propfind>"
2005-11-02 22:19:24 +03:00
# define LOCK_REQUEST "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<D:lockinfo xmlns:D=\"DAV:\">\n<D:lockscope><D:exclusive / >< / D:lockscope>\n<D:locktype><D:write / >< / D:locktype>\n<D:owner>\n<D:href>mailto:%s< / D:href>\n< / D:owner>\n< / D:lockinfo>"
2005-11-05 01:22:35 +03:00
# define LOCK_TIME 600
# define LOCK_REFRESH 30
2014-03-25 17:23:26 +04:00
/* Remember to update object flag allocation in object.h */
2006-04-17 05:12:49 +04:00
# define LOCAL (1u<<16)
# define REMOTE (1u<<17)
# define FETCHING (1u<<18)
# define PUSHING (1u<<19)
2006-03-08 03:13:20 +03:00
2006-03-20 21:31:06 +03:00
/* We allow "recursive" symbolic refs. Only within reason, though */
# define MAXDEPTH 5
2006-08-15 21:23:48 +04:00
static int pushing ;
static int aborted ;
2006-03-20 22:50:51 +03:00
static signed char remote_dir_exists [ 256 ] ;
2005-11-02 22:19:24 +03:00
2006-08-15 21:23:48 +04:00
static int push_verbosely ;
2007-11-10 02:32:10 +03:00
static int push_all = MATCH_REFS_NONE ;
2006-08-15 21:23:48 +04:00
static int force_all ;
2007-10-16 08:35:22 +04:00
static int dry_run ;
2009-10-31 03:47:30 +03:00
static int helper_status ;
2005-11-02 22:19:24 +03:00
2006-08-15 21:23:48 +04:00
static struct object_list * objects ;
2006-03-08 03:13:20 +03:00
2011-03-16 10:08:34 +03:00
struct repo {
2005-11-02 22:19:24 +03:00
char * url ;
2008-12-23 11:31:15 +03:00
char * path ;
2006-03-08 03:13:20 +03:00
int path_len ;
2006-03-11 07:18:18 +03:00
int has_info_refs ;
int can_update_info_refs ;
int has_info_packs ;
2005-11-02 22:19:24 +03:00
struct packed_git * packs ;
2006-03-11 07:18:12 +03:00
struct remote_lock * locks ;
2005-11-02 22:19:24 +03:00
} ;
2009-03-19 02:43:53 +03:00
static struct repo * repo ;
2005-11-02 22:19:24 +03:00
enum transfer_state {
2006-03-11 07:18:18 +03:00
NEED_FETCH ,
RUN_FETCH_LOOSE ,
RUN_FETCH_PACKED ,
2005-11-02 22:19:24 +03:00
NEED_PUSH ,
RUN_MKCOL ,
RUN_PUT ,
RUN_MOVE ,
ABORTED ,
2010-05-14 13:31:35 +04:00
COMPLETE
2005-11-02 22:19:24 +03:00
} ;
2011-03-16 10:08:34 +03:00
struct transfer_request {
2006-03-08 03:13:20 +03:00
struct object * obj ;
2005-11-02 22:19:24 +03:00
char * url ;
char * dest ;
2006-03-08 03:13:20 +03:00
struct remote_lock * lock ;
2005-11-02 22:19:24 +03:00
struct curl_slist * headers ;
struct buffer buffer ;
enum transfer_state state ;
CURLcode curl_result ;
char errorstr [ CURL_ERROR_SIZE ] ;
long http_code ;
2006-03-11 07:18:18 +03:00
void * userData ;
2005-11-02 22:19:24 +03:00
struct active_request_slot * slot ;
struct transfer_request * next ;
} ;
2006-08-15 21:23:48 +04:00
static struct transfer_request * request_queue_head ;
2005-11-02 22:19:24 +03:00
2011-03-16 10:08:34 +03:00
struct xml_ctx {
2005-11-18 22:03:18 +03:00
char * name ;
int len ;
char * cdata ;
void ( * userFunc ) ( struct xml_ctx * ctx , int tag_closed ) ;
void * userData ;
} ;
2011-03-16 10:08:34 +03:00
struct remote_lock {
2005-11-05 01:22:35 +03:00
char * url ;
2005-11-05 01:22:31 +03:00
char * owner ;
2005-11-05 01:22:35 +03:00
char * token ;
use a hash of the lock token as the suffix for PUT/MOVE
After 753bc91 ("Remove the requirement opaquelocktoken uri scheme"),
lock tokens are in the URI forms in which they are received from the
server, eg. 'opaquelocktoken:', 'urn:uuid:'.
However, "start_put" (and consequently "start_move"), which attempts to
create a unique temporary file using the UUID of the lock token,
inadvertently uses the lock token in its URI form. These file
operations on the server may not be successful (specifically, in
Windows), due to the colon ':' character from the URI form of the lock
token in the file path.
This patch uses a hash of the lock token instead, guaranteeing only
"safe" characters (a-f, 0-9) are used in the file path.
The token's hash is generated when the lock token is received from the
server in handle_new_lock_ctx, minimizing the number of times of
hashing.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-14 12:52:14 +03:00
char tmpfile_suffix [ 41 ] ;
2005-11-05 01:22:31 +03:00
time_t start_time ;
long timeout ;
2005-11-05 01:22:35 +03:00
int refreshing ;
2006-03-08 03:13:20 +03:00
struct remote_lock * next ;
} ;
2006-03-11 07:18:08 +03:00
/* Flags that control remote_ls processing */
# define PROCESS_FILES (1u << 0)
# define PROCESS_DIRS (1u << 1)
# define RECURSIVE (1u << 2)
/* Flags that remote_ls passes to callback functions */
# define IS_DIR (1u << 0)
2011-03-16 10:08:34 +03:00
struct remote_ls_ctx {
2006-03-11 07:18:08 +03:00
char * path ;
void ( * userFunc ) ( struct remote_ls_ctx * ls ) ;
void * userData ;
int flags ;
char * dentry_name ;
int dentry_flags ;
struct remote_ls_ctx * parent ;
2005-11-05 01:22:31 +03:00
} ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
/* get_dav_token_headers options */
enum dav_header_flag {
DAV_HEADER_IF = ( 1u < < 0 ) ,
DAV_HEADER_LOCK = ( 1u < < 1 ) ,
DAV_HEADER_TIMEOUT = ( 1u < < 2 )
} ;
2011-05-03 19:47:28 +04:00
static char * xml_entities ( const char * s )
2009-04-10 02:25:37 +04:00
{
struct strbuf buf = STRBUF_INIT ;
2012-11-25 15:08:35 +04:00
strbuf_addstr_xml_quoted ( & buf , s ) ;
2009-04-10 02:25:37 +04:00
return strbuf_detach ( & buf , NULL ) ;
}
2011-05-03 19:47:29 +04:00
static void curl_setup_http_get ( CURL * curl , const char * url ,
const char * custom_req )
{
curl_easy_setopt ( curl , CURLOPT_HTTPGET , 1 ) ;
curl_easy_setopt ( curl , CURLOPT_URL , url ) ;
curl_easy_setopt ( curl , CURLOPT_CUSTOMREQUEST , custom_req ) ;
curl_easy_setopt ( curl , CURLOPT_WRITEFUNCTION , fwrite_null ) ;
}
static void curl_setup_http ( CURL * curl , const char * url ,
const char * custom_req , struct buffer * buffer ,
curl_write_callback write_fn )
{
curl_easy_setopt ( curl , CURLOPT_PUT , 1 ) ;
curl_easy_setopt ( curl , CURLOPT_URL , url ) ;
curl_easy_setopt ( curl , CURLOPT_INFILE , buffer ) ;
curl_easy_setopt ( curl , CURLOPT_INFILESIZE , buffer - > buf . len ) ;
curl_easy_setopt ( curl , CURLOPT_READFUNCTION , fread_buffer ) ;
# ifndef NO_CURL_IOCTL
curl_easy_setopt ( curl , CURLOPT_IOCTLFUNCTION , ioctl_buffer ) ;
2014-07-06 04:43:48 +04:00
curl_easy_setopt ( curl , CURLOPT_IOCTLDATA , buffer ) ;
2011-05-03 19:47:29 +04:00
# endif
curl_easy_setopt ( curl , CURLOPT_WRITEFUNCTION , write_fn ) ;
curl_easy_setopt ( curl , CURLOPT_NOBODY , 0 ) ;
curl_easy_setopt ( curl , CURLOPT_CUSTOMREQUEST , custom_req ) ;
curl_easy_setopt ( curl , CURLOPT_UPLOAD , 1 ) ;
}
2009-01-25 11:04:15 +03:00
static struct curl_slist * get_dav_token_headers ( struct remote_lock * lock , enum dav_header_flag options )
{
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
struct strbuf buf = STRBUF_INIT ;
2016-04-27 15:20:37 +03:00
struct curl_slist * dav_headers = http_copy_default_headers ( ) ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
2009-01-25 11:04:15 +03:00
if ( options & DAV_HEADER_IF ) {
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
strbuf_addf ( & buf , " If: (<%s>) " , lock - > token ) ;
dav_headers = curl_slist_append ( dav_headers , buf . buf ) ;
strbuf_reset ( & buf ) ;
}
2009-01-25 11:04:15 +03:00
if ( options & DAV_HEADER_LOCK ) {
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
strbuf_addf ( & buf , " Lock-Token: <%s> " , lock - > token ) ;
dav_headers = curl_slist_append ( dav_headers , buf . buf ) ;
strbuf_reset ( & buf ) ;
}
2009-01-25 11:04:15 +03:00
if ( options & DAV_HEADER_TIMEOUT ) {
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
strbuf_addf ( & buf , " Timeout: Second-%ld " , lock - > timeout ) ;
dav_headers = curl_slist_append ( dav_headers , buf . buf ) ;
strbuf_reset ( & buf ) ;
}
strbuf_release ( & buf ) ;
return dav_headers ;
}
2005-11-18 22:02:58 +03:00
static void finish_request ( struct transfer_request * request ) ;
2006-03-11 07:18:18 +03:00
static void release_request ( struct transfer_request * request ) ;
2005-11-02 22:19:24 +03:00
2005-11-18 22:02:58 +03:00
static void process_response ( void * callback_data )
2005-11-02 22:19:24 +03:00
{
2005-11-18 22:02:58 +03:00
struct transfer_request * request =
( struct transfer_request * ) callback_data ;
2005-11-02 22:19:24 +03:00
2005-11-18 22:02:58 +03:00
finish_request ( request ) ;
2005-11-02 22:19:24 +03:00
}
2006-06-07 01:26:57 +04:00
# ifdef USE_CURL_MULTI
2009-02-03 09:24:40 +03:00
2006-03-11 07:18:18 +03:00
static void start_fetch_loose ( struct transfer_request * request )
{
struct active_request_slot * slot ;
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
struct http_object_request * obj_req ;
2006-03-11 07:18:18 +03:00
2015-11-10 05:22:29 +03:00
obj_req = new_http_object_request ( repo - > url , request - > obj - > oid . hash ) ;
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
if ( obj_req = = NULL ) {
2006-03-11 07:18:18 +03:00
request - > state = ABORTED ;
return ;
}
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
slot = obj_req - > slot ;
2006-03-11 07:18:18 +03:00
slot - > callback_func = process_response ;
slot - > callback_data = request ;
request - > slot = slot ;
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
request - > userData = obj_req ;
2006-03-11 07:18:18 +03:00
/* Try to get the request started, abort the request on error */
request - > state = RUN_FETCH_LOOSE ;
if ( ! start_active_slot ( slot ) ) {
fprintf ( stderr , " Unable to start GET request \n " ) ;
2009-03-19 02:43:53 +03:00
repo - > can_update_info_refs = 0 ;
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
release_http_object_request ( obj_req ) ;
2006-03-11 07:18:18 +03:00
release_request ( request ) ;
}
}
2006-06-07 01:26:57 +04:00
static void start_mkcol ( struct transfer_request * request )
{
2015-11-10 05:22:28 +03:00
char * hex = oid_to_hex ( & request - > obj - > oid ) ;
2006-06-07 01:26:57 +04:00
struct active_request_slot * slot ;
2009-03-19 02:43:53 +03:00
request - > url = get_remote_object_url ( repo - > url , hex , 1 ) ;
2006-06-07 01:26:57 +04:00
slot = get_active_slot ( ) ;
slot - > callback_func = process_response ;
slot - > callback_data = request ;
2011-05-03 19:47:29 +04:00
curl_setup_http_get ( slot - > curl , request - > url , DAV_MKCOL ) ;
2006-06-07 01:26:57 +04:00
curl_easy_setopt ( slot - > curl , CURLOPT_ERRORBUFFER , request - > errorstr ) ;
if ( start_active_slot ( slot ) ) {
request - > slot = slot ;
request - > state = RUN_MKCOL ;
} else {
request - > state = ABORTED ;
free ( request - > url ) ;
request - > url = NULL ;
}
}
# endif
2006-03-11 07:18:18 +03:00
static void start_fetch_packed ( struct transfer_request * request )
{
struct packed_git * target ;
struct transfer_request * check_request = request_queue_head ;
2009-06-06 12:44:01 +04:00
struct http_pack_request * preq ;
2006-03-11 07:18:18 +03:00
2015-11-10 05:22:29 +03:00
target = find_sha1_pack ( request - > obj - > oid . hash , repo - > packs ) ;
2006-03-11 07:18:18 +03:00
if ( ! target ) {
2015-11-10 05:22:28 +03:00
fprintf ( stderr , " Unable to fetch %s, will not be able to update server info refs \n " , oid_to_hex ( & request - > obj - > oid ) ) ;
2009-03-19 02:43:53 +03:00
repo - > can_update_info_refs = 0 ;
2006-03-11 07:18:18 +03:00
release_request ( request ) ;
return ;
}
fprintf ( stderr , " Fetching pack %s \n " , sha1_to_hex ( target - > sha1 ) ) ;
2015-11-10 05:22:28 +03:00
fprintf ( stderr , " which contains %s \n " , oid_to_hex ( & request - > obj - > oid ) ) ;
2006-03-11 07:18:18 +03:00
2009-06-06 12:44:01 +04:00
preq = new_http_pack_request ( target , repo - > url ) ;
if ( preq = = NULL ) {
repo - > can_update_info_refs = 0 ;
return ;
}
preq - > lst = & repo - > packs ;
2006-03-11 07:18:18 +03:00
/* Make sure there isn't another open request for this pack */
while ( check_request ) {
if ( check_request - > state = = RUN_FETCH_PACKED & &
2009-06-06 12:44:01 +04:00
! strcmp ( check_request - > url , preq - > url ) ) {
release_http_pack_request ( preq ) ;
2006-03-11 07:18:18 +03:00
release_request ( request ) ;
return ;
}
check_request = check_request - > next ;
}
2009-06-06 12:44:01 +04:00
preq - > slot - > callback_func = process_response ;
preq - > slot - > callback_data = request ;
request - > slot = preq - > slot ;
request - > userData = preq ;
2006-03-11 07:18:18 +03:00
/* Try to get the request started, abort the request on error */
request - > state = RUN_FETCH_PACKED ;
2009-06-06 12:44:01 +04:00
if ( ! start_active_slot ( preq - > slot ) ) {
2006-03-11 07:18:18 +03:00
fprintf ( stderr , " Unable to start GET request \n " ) ;
2009-06-06 12:44:01 +04:00
release_http_pack_request ( preq ) ;
2009-03-19 02:43:53 +03:00
repo - > can_update_info_refs = 0 ;
2006-03-11 07:18:18 +03:00
release_request ( request ) ;
}
}
2005-11-02 22:19:24 +03:00
static void start_put ( struct transfer_request * request )
{
2015-11-10 05:22:28 +03:00
char * hex = oid_to_hex ( & request - > obj - > oid ) ;
2005-11-02 22:19:24 +03:00
struct active_request_slot * slot ;
2009-01-31 02:51:55 +03:00
struct strbuf buf = STRBUF_INIT ;
2007-02-26 22:55:59 +03:00
enum object_type type ;
2005-11-02 22:19:24 +03:00
char hdr [ 50 ] ;
void * unpacked ;
unsigned long len ;
int hdrlen ;
ssize_t size ;
2011-06-10 22:52:15 +04:00
git_zstream stream ;
2005-11-02 22:19:24 +03:00
2015-11-10 05:22:29 +03:00
unpacked = read_sha1_file ( request - > obj - > oid . hash , & type , & len ) ;
2015-09-25 00:06:42 +03:00
hdrlen = xsnprintf ( hdr , sizeof ( hdr ) , " %s %lu " , typename ( type ) , len ) + 1 ;
2005-11-02 22:19:24 +03:00
/* Set it up */
2011-06-10 21:55:10 +04:00
git_deflate_init ( & stream , zlib_compression_level ) ;
2011-06-10 22:18:17 +04:00
size = git_deflate_bound ( & stream , len + hdrlen ) ;
2007-12-09 22:30:59 +03:00
strbuf_init ( & request - > buffer . buf , size ) ;
request - > buffer . posn = 0 ;
2005-11-02 22:19:24 +03:00
/* Compress it */
2007-12-09 22:30:59 +03:00
stream . next_out = ( unsigned char * ) request - > buffer . buf . buf ;
2005-11-02 22:19:24 +03:00
stream . avail_out = size ;
/* First header.. */
stream . next_in = ( void * ) hdr ;
stream . avail_in = hdrlen ;
2011-06-10 21:55:10 +04:00
while ( git_deflate ( & stream , 0 ) = = Z_OK )
; /* nothing */
2005-11-02 22:19:24 +03:00
/* Then the data itself.. */
stream . next_in = unpacked ;
stream . avail_in = len ;
2011-06-10 21:55:10 +04:00
while ( git_deflate ( & stream , Z_FINISH ) = = Z_OK )
; /* nothing */
git_deflate_end ( & stream ) ;
2005-11-02 22:19:24 +03:00
free ( unpacked ) ;
2007-12-09 22:30:59 +03:00
request - > buffer . buf . len = stream . total_out ;
2005-11-02 22:19:24 +03:00
2009-01-31 02:51:55 +03:00
strbuf_addstr ( & buf , " Destination: " ) ;
2009-03-19 02:43:53 +03:00
append_remote_object_url ( & buf , repo - > url , hex , 0 ) ;
2009-01-31 02:51:55 +03:00
request - > dest = strbuf_detach ( & buf , NULL ) ;
2009-03-19 02:43:53 +03:00
append_remote_object_url ( & buf , repo - > url , hex , 0 ) ;
use a hash of the lock token as the suffix for PUT/MOVE
After 753bc91 ("Remove the requirement opaquelocktoken uri scheme"),
lock tokens are in the URI forms in which they are received from the
server, eg. 'opaquelocktoken:', 'urn:uuid:'.
However, "start_put" (and consequently "start_move"), which attempts to
create a unique temporary file using the UUID of the lock token,
inadvertently uses the lock token in its URI form. These file
operations on the server may not be successful (specifically, in
Windows), due to the colon ':' character from the URI form of the lock
token in the file path.
This patch uses a hash of the lock token instead, guaranteeing only
"safe" characters (a-f, 0-9) are used in the file path.
The token's hash is generated when the lock token is received from the
server in handle_new_lock_ctx, minimizing the number of times of
hashing.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-14 12:52:14 +03:00
strbuf_add ( & buf , request - > lock - > tmpfile_suffix , 41 ) ;
2009-01-31 02:51:55 +03:00
request - > url = strbuf_detach ( & buf , NULL ) ;
2005-11-02 22:19:24 +03:00
slot = get_active_slot ( ) ;
2005-11-18 22:02:58 +03:00
slot - > callback_func = process_response ;
slot - > callback_data = request ;
2011-05-03 19:47:29 +04:00
curl_setup_http ( slot - > curl , request - > url , DAV_PUT ,
& request - > buffer , fwrite_null ) ;
2005-11-02 22:19:24 +03:00
if ( start_active_slot ( slot ) ) {
request - > slot = slot ;
request - > state = RUN_PUT ;
} else {
request - > state = ABORTED ;
free ( request - > url ) ;
2005-11-18 22:03:25 +03:00
request - > url = NULL ;
2005-11-02 22:19:24 +03:00
}
}
static void start_move ( struct transfer_request * request )
{
struct active_request_slot * slot ;
2016-04-27 15:20:37 +03:00
struct curl_slist * dav_headers = http_copy_default_headers ( ) ;
2005-11-02 22:19:24 +03:00
slot = get_active_slot ( ) ;
2005-11-18 22:02:58 +03:00
slot - > callback_func = process_response ;
slot - > callback_data = request ;
2011-05-03 19:47:29 +04:00
curl_setup_http_get ( slot - > curl , request - > url , DAV_MOVE ) ;
2005-11-02 22:19:24 +03:00
dav_headers = curl_slist_append ( dav_headers , request - > dest ) ;
dav_headers = curl_slist_append ( dav_headers , " Overwrite: T " ) ;
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
if ( start_active_slot ( slot ) ) {
request - > slot = slot ;
request - > state = RUN_MOVE ;
} else {
request - > state = ABORTED ;
free ( request - > url ) ;
2005-11-18 22:03:25 +03:00
request - > url = NULL ;
2005-11-02 22:19:24 +03:00
}
}
2006-03-11 07:18:12 +03:00
static int refresh_lock ( struct remote_lock * lock )
2005-11-05 01:22:35 +03:00
{
struct active_request_slot * slot ;
2006-03-11 07:18:01 +03:00
struct slot_results results ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
struct curl_slist * dav_headers ;
2006-03-11 07:18:12 +03:00
int rc = 0 ;
2005-11-05 01:22:35 +03:00
2006-03-11 07:18:12 +03:00
lock - > refreshing = 1 ;
2005-11-05 01:22:35 +03:00
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
dav_headers = get_dav_token_headers ( lock , DAV_HEADER_IF | DAV_HEADER_TIMEOUT ) ;
2005-11-05 01:22:35 +03:00
2006-03-11 07:18:12 +03:00
slot = get_active_slot ( ) ;
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http_get ( slot - > curl , lock - > url , DAV_LOCK ) ;
2006-03-11 07:18:12 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
2005-11-05 01:22:35 +03:00
2006-03-11 07:18:12 +03:00
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
if ( results . curl_result ! = CURLE_OK ) {
fprintf ( stderr , " LOCK HTTP error %ld \n " ,
results . http_code ) ;
} else {
lock - > start_time = time ( NULL ) ;
rc = 1 ;
}
}
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:12 +03:00
lock - > refreshing = 0 ;
curl_slist_free_all ( dav_headers ) ;
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:12 +03:00
return rc ;
}
2006-04-02 15:13:10 +04:00
static void check_locks ( void )
2006-03-11 07:18:12 +03:00
{
2009-03-19 02:43:53 +03:00
struct remote_lock * lock = repo - > locks ;
2006-03-11 07:18:12 +03:00
time_t current_time = time ( NULL ) ;
int time_remaining ;
while ( lock ) {
time_remaining = lock - > start_time + lock - > timeout -
current_time ;
if ( ! lock - > refreshing & & time_remaining < LOCK_REFRESH ) {
if ( ! refresh_lock ( lock ) ) {
fprintf ( stderr ,
" Unable to refresh lock for %s \n " ,
lock - > url ) ;
aborted = 1 ;
return ;
2006-03-08 03:13:20 +03:00
}
2005-11-05 01:22:35 +03:00
}
2006-03-11 07:18:12 +03:00
lock = lock - > next ;
2005-11-05 01:22:35 +03:00
}
2006-03-08 03:13:20 +03:00
}
2005-11-05 01:22:35 +03:00
2006-03-08 03:13:20 +03:00
static void release_request ( struct transfer_request * request )
{
struct transfer_request * entry = request_queue_head ;
if ( request = = request_queue_head ) {
request_queue_head = request - > next ;
} else {
while ( entry - > next ! = NULL & & entry - > next ! = request )
entry = entry - > next ;
if ( entry - > next = = request )
entry - > next = entry - > next - > next ;
}
Avoid unnecessary "if-before-free" tests.
This change removes all obvious useless if-before-free tests.
E.g., it replaces code like this:
if (some_expression)
free (some_expression);
with the now-equivalent:
free (some_expression);
It is equivalent not just because POSIX has required free(NULL)
to work for a long time, but simply because it has worked for
so long that no reasonable porting target fails the test.
Here's some evidence from nearly 1.5 years ago:
http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html
FYI, the change below was prepared by running the following:
git ls-files -z | xargs -0 \
perl -0x3b -pi -e \
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(free\s*\(\s*\1\s*\))/$2/s'
Note however, that it doesn't handle brace-enclosed blocks like
"if (x) { free (x); }". But that's ok, since there were none like
that in git sources.
Beware: if you do use the above snippet, note that it can
produce syntactically invalid C code. That happens when the
affected "if"-statement has a matching "else".
E.g., it would transform this
if (x)
free (x);
else
foo ();
into this:
free (x);
else
foo ();
There were none of those here, either.
If you're interested in automating detection of the useless
tests, you might like the useless-if-before-free script in gnulib:
[it *does* detect brace-enclosed free statements, and has a --name=S
option to make it detect free-like functions with different names]
http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=build-aux/useless-if-before-free
Addendum:
Remove one more (in imap-send.c), spotted by Jean-Luc Herren <jlh@gmx.ch>.
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-31 20:26:32 +03:00
free ( request - > url ) ;
2006-03-08 03:13:20 +03:00
free ( request ) ;
2005-11-05 01:22:35 +03:00
}
2005-11-02 22:19:24 +03:00
static void finish_request ( struct transfer_request * request )
{
2009-06-06 12:44:01 +04:00
struct http_pack_request * preq ;
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
struct http_object_request * obj_req ;
2006-03-11 07:18:18 +03:00
request - > curl_result = request - > slot - > curl_result ;
2005-11-02 22:19:24 +03:00
request - > http_code = request - > slot - > http_code ;
request - > slot = NULL ;
2005-11-05 01:22:35 +03:00
2006-03-08 03:13:20 +03:00
/* Keep locks active */
2006-03-11 07:18:12 +03:00
check_locks ( ) ;
2005-11-05 01:22:35 +03:00
2005-11-02 22:19:24 +03:00
if ( request - > headers ! = NULL )
curl_slist_free_all ( request - > headers ) ;
2005-11-18 22:03:25 +03:00
/* URL is reused for MOVE after PUT */
if ( request - > state ! = RUN_PUT ) {
free ( request - > url ) ;
request - > url = NULL ;
2006-03-08 03:13:20 +03:00
}
2005-11-18 22:03:25 +03:00
2006-03-08 03:13:20 +03:00
if ( request - > state = = RUN_MKCOL ) {
2005-11-02 22:19:24 +03:00
if ( request - > curl_result = = CURLE_OK | |
request - > http_code = = 405 ) {
2015-11-10 05:22:29 +03:00
remote_dir_exists [ request - > obj - > oid . hash [ 0 ] ] = 1 ;
2005-11-02 22:19:24 +03:00
start_put ( request ) ;
} else {
fprintf ( stderr , " MKCOL %s failed, aborting (%d/%ld) \n " ,
2015-11-10 05:22:28 +03:00
oid_to_hex ( & request - > obj - > oid ) ,
2005-11-02 22:19:24 +03:00
request - > curl_result , request - > http_code ) ;
request - > state = ABORTED ;
aborted = 1 ;
}
} else if ( request - > state = = RUN_PUT ) {
if ( request - > curl_result = = CURLE_OK ) {
start_move ( request ) ;
} else {
fprintf ( stderr , " PUT %s failed, aborting (%d/%ld) \n " ,
2015-11-10 05:22:28 +03:00
oid_to_hex ( & request - > obj - > oid ) ,
2005-11-02 22:19:24 +03:00
request - > curl_result , request - > http_code ) ;
request - > state = ABORTED ;
aborted = 1 ;
}
} else if ( request - > state = = RUN_MOVE ) {
if ( request - > curl_result = = CURLE_OK ) {
2006-03-11 07:18:33 +03:00
if ( push_verbosely )
fprintf ( stderr , " sent %s \n " ,
2015-11-10 05:22:28 +03:00
oid_to_hex ( & request - > obj - > oid ) ) ;
2006-03-08 03:13:20 +03:00
request - > obj - > flags | = REMOTE ;
release_request ( request ) ;
2005-11-02 22:19:24 +03:00
} else {
fprintf ( stderr , " MOVE %s failed, aborting (%d/%ld) \n " ,
2015-11-10 05:22:28 +03:00
oid_to_hex ( & request - > obj - > oid ) ,
2005-11-02 22:19:24 +03:00
request - > curl_result , request - > http_code ) ;
request - > state = ABORTED ;
aborted = 1 ;
}
2006-03-11 07:18:18 +03:00
} else if ( request - > state = = RUN_FETCH_LOOSE ) {
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
obj_req = ( struct http_object_request * ) request - > userData ;
2006-03-11 07:18:18 +03:00
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
if ( finish_http_object_request ( obj_req ) = = 0 )
if ( obj_req - > rename = = 0 )
request - > obj - > flags | = ( LOCAL | REMOTE ) ;
2006-03-11 07:18:18 +03:00
/* Try fetching packed if necessary */
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
if ( request - > obj - > flags & LOCAL ) {
release_http_object_request ( obj_req ) ;
2006-03-11 07:18:18 +03:00
release_request ( request ) ;
http*: add helper methods for fetching objects (loose)
The code handling the fetching of loose objects in http-push.c and
http-walker.c have been refactored into new methods and a new struct
(object_http_request) in http.c. They are not meant to be invoked
elsewhere.
The new methods in http.c are
- new_http_object_request
- process_http_object_request
- finish_http_object_request
- abort_http_object_request
- release_http_object_request
and the new struct is http_object_request.
RANGER_HEADER_SIZE and no_pragma_header is no longer made available
outside of http.c, since after the above changes, there are no other
instances of usage outside of http.c.
Remove members of the transfer_request struct in http-push.c and
http-walker.c, including filename, real_sha1 and zret, as they are used
no longer used.
Move the methods append_remote_object_url() and get_remote_object_url()
from http-push.c to http.c. Additionally, get_remote_object_url() is no
longer defined only when USE_CURL_MULTI is defined, since
non-USE_CURL_MULTI code in http.c uses it (namely, in
new_http_object_request()).
Refactor code from http-push.c::start_fetch_loose() and
http-walker.c::start_object_fetch_request() that deals with the details
of coming up with the filename to store the retrieved object, resuming
a previously aborted request, and making a new curl request, into a new
function, new_http_object_request().
Refactor code from http-walker.c::process_object_request() into the
function, process_http_object_request().
Refactor code from http-push.c::finish_request() and
http-walker.c::finish_object_request() into a new function,
finish_http_object_request(). It returns the result of the
move_temp_to_file() invocation.
Add a function, release_http_object_request(), which cleans up object
request data. http-push.c and http-walker.c invoke this function
separately; http-push.c::release_request() and
http-walker.c::release_object_request() do not invoke this function.
Add a function, abort_http_object_request(), which unlink()s the object
file and invokes release_http_object_request(). Update
http-walker.c::abort_object_request() to use this.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-06 12:44:02 +04:00
} else
2006-03-11 07:18:18 +03:00
start_fetch_packed ( request ) ;
} else if ( request - > state = = RUN_FETCH_PACKED ) {
2009-06-06 12:44:01 +04:00
int fail = 1 ;
2006-03-11 07:18:18 +03:00
if ( request - > curl_result ! = CURLE_OK ) {
fprintf ( stderr , " Unable to get pack file %s \n %s " ,
request - > url , curl_errorstr ) ;
} else {
2009-06-06 12:44:01 +04:00
preq = ( struct http_pack_request * ) request - > userData ;
if ( preq ) {
2009-10-31 03:47:20 +03:00
if ( finish_http_pack_request ( preq ) = = 0 )
2009-06-06 12:44:01 +04:00
fail = 0 ;
release_http_pack_request ( preq ) ;
2006-03-11 07:18:18 +03:00
}
}
2009-06-06 12:44:01 +04:00
if ( fail )
repo - > can_update_info_refs = 0 ;
2006-03-11 07:18:18 +03:00
release_request ( request ) ;
2005-11-02 22:19:24 +03:00
}
}
2006-06-06 20:41:32 +04:00
# ifdef USE_CURL_MULTI
2009-06-06 12:43:27 +04:00
static int is_running_queue ;
2007-09-11 07:02:34 +04:00
static int fill_active_slot ( void * unused )
2005-11-02 22:19:24 +03:00
{
2009-03-16 00:01:20 +03:00
struct transfer_request * request ;
2005-11-02 22:19:24 +03:00
2009-06-06 12:43:27 +04:00
if ( aborted | | ! is_running_queue )
2007-09-11 07:02:28 +04:00
return 0 ;
2005-11-02 22:19:24 +03:00
2007-09-11 07:02:28 +04:00
for ( request = request_queue_head ; request ; request = request - > next ) {
2006-03-11 07:18:18 +03:00
if ( request - > state = = NEED_FETCH ) {
start_fetch_loose ( request ) ;
2007-09-11 07:02:28 +04:00
return 1 ;
2006-03-11 07:18:18 +03:00
} else if ( pushing & & request - > state = = NEED_PUSH ) {
2015-11-10 05:22:29 +03:00
if ( remote_dir_exists [ request - > obj - > oid . hash [ 0 ] ] = = 1 ) {
2005-11-07 22:39:37 +03:00
start_put ( request ) ;
2006-03-08 03:13:20 +03:00
} else {
2005-11-07 22:39:37 +03:00
start_mkcol ( request ) ;
2006-03-08 03:13:20 +03:00
}
2007-09-11 07:02:28 +04:00
return 1 ;
2005-11-02 22:19:24 +03:00
}
2006-03-08 03:13:20 +03:00
}
2007-09-11 07:02:28 +04:00
return 0 ;
2005-11-02 22:19:24 +03:00
}
2006-06-06 20:41:32 +04:00
# endif
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
static void get_remote_object_list ( unsigned char parent ) ;
2006-03-11 07:18:18 +03:00
static void add_fetch_request ( struct object * obj )
{
struct transfer_request * request ;
check_locks ( ) ;
/*
* Don ' t fetch the object if it ' s known to exist locally
* or is already in the request queue
*/
2015-11-10 05:22:29 +03:00
if ( remote_dir_exists [ obj - > oid . hash [ 0 ] ] = = - 1 )
get_remote_object_list ( obj - > oid . hash [ 0 ] ) ;
2006-03-11 07:18:18 +03:00
if ( obj - > flags & ( LOCAL | FETCHING ) )
return ;
obj - > flags | = FETCHING ;
request = xmalloc ( sizeof ( * request ) ) ;
request - > obj = obj ;
request - > url = NULL ;
request - > lock = NULL ;
request - > headers = NULL ;
request - > state = NEED_FETCH ;
request - > next = request_queue_head ;
request_queue_head = request ;
2006-06-06 20:41:32 +04:00
# ifdef USE_CURL_MULTI
2006-03-11 07:18:18 +03:00
fill_active_slots ( ) ;
step_active_slots ( ) ;
2006-06-06 20:41:32 +04:00
# endif
2006-03-11 07:18:18 +03:00
}
2006-03-11 07:18:33 +03:00
static int add_send_request ( struct object * obj , struct remote_lock * lock )
2005-11-02 22:19:24 +03:00
{
2013-07-19 01:35:26 +04:00
struct transfer_request * request ;
2005-11-02 22:19:24 +03:00
struct packed_git * target ;
2006-03-11 07:18:12 +03:00
/* Keep locks active */
check_locks ( ) ;
2006-03-08 03:13:20 +03:00
/*
* Don ' t push the object if it ' s known to exist on the remote
* or is already in the request queue
*/
2015-11-10 05:22:29 +03:00
if ( remote_dir_exists [ obj - > oid . hash [ 0 ] ] = = - 1 )
get_remote_object_list ( obj - > oid . hash [ 0 ] ) ;
2006-03-08 03:13:20 +03:00
if ( obj - > flags & ( REMOTE | PUSHING ) )
2006-03-11 07:18:33 +03:00
return 0 ;
2015-11-10 05:22:29 +03:00
target = find_sha1_pack ( obj - > oid . hash , repo - > packs ) ;
2006-03-08 03:13:20 +03:00
if ( target ) {
obj - > flags | = REMOTE ;
2006-03-11 07:18:33 +03:00
return 0 ;
2006-03-08 03:13:20 +03:00
}
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
obj - > flags | = PUSHING ;
2005-11-02 22:19:24 +03:00
request = xmalloc ( sizeof ( * request ) ) ;
2006-03-08 03:13:20 +03:00
request - > obj = obj ;
2005-11-02 22:19:24 +03:00
request - > url = NULL ;
2005-11-05 01:22:31 +03:00
request - > lock = lock ;
2005-11-02 22:19:24 +03:00
request - > headers = NULL ;
2006-03-08 03:13:20 +03:00
request - > state = NEED_PUSH ;
2005-11-05 01:22:18 +03:00
request - > next = request_queue_head ;
request_queue_head = request ;
2005-11-18 22:02:58 +03:00
2006-06-06 20:41:32 +04:00
# ifdef USE_CURL_MULTI
2005-11-18 22:02:58 +03:00
fill_active_slots ( ) ;
step_active_slots ( ) ;
2006-06-06 20:41:32 +04:00
# endif
2006-03-11 07:18:33 +03:00
return 1 ;
2005-11-02 22:19:24 +03:00
}
2005-11-09 01:18:31 +03:00
static int fetch_indices ( void )
2005-11-02 22:19:24 +03:00
{
2009-06-06 12:43:59 +04:00
int ret ;
2005-11-02 22:19:24 +03:00
if ( push_verbosely )
fprintf ( stderr , " Getting pack list \n " ) ;
2006-03-11 07:18:33 +03:00
2009-06-06 12:43:59 +04:00
switch ( http_get_info_packs ( repo - > url , & repo - > packs ) ) {
case HTTP_OK :
case HTTP_MISSING_TARGET :
ret = 0 ;
break ;
default :
ret = - 1 ;
2005-11-02 22:19:24 +03:00
}
2009-06-06 12:43:59 +04:00
return ret ;
2005-11-02 22:19:24 +03:00
}
2014-06-20 01:58:10 +04:00
static void one_remote_object ( const unsigned char * sha1 )
2006-03-08 03:13:20 +03:00
{
struct object * obj ;
obj = lookup_object ( sha1 ) ;
if ( ! obj )
obj = parse_object ( sha1 ) ;
/* Ignore remote objects that don't exist locally */
if ( ! obj )
return ;
obj - > flags | = REMOTE ;
if ( ! object_list_contains ( objects , obj ) )
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
object_list_insert ( obj , & objects ) ;
2006-03-08 03:13:20 +03:00
}
2005-11-18 22:03:18 +03:00
static void handle_lockprop_ctx ( struct xml_ctx * ctx , int tag_closed )
2005-11-05 01:22:31 +03:00
{
2005-11-18 22:03:18 +03:00
int * lock_flags = ( int * ) ctx - > userData ;
if ( tag_closed ) {
if ( ! strcmp ( ctx - > name , DAV_CTX_LOCKENTRY ) ) {
if ( ( * lock_flags & DAV_PROP_LOCKEX ) & &
( * lock_flags & DAV_PROP_LOCKWR ) ) {
* lock_flags | = DAV_LOCK_OK ;
}
* lock_flags & = DAV_LOCK_OK ;
} else if ( ! strcmp ( ctx - > name , DAV_CTX_LOCKTYPE_WRITE ) ) {
* lock_flags | = DAV_PROP_LOCKWR ;
} else if ( ! strcmp ( ctx - > name , DAV_CTX_LOCKTYPE_EXCLUSIVE ) ) {
* lock_flags | = DAV_PROP_LOCKEX ;
}
}
2005-11-05 01:22:31 +03:00
}
2005-11-18 22:03:18 +03:00
static void handle_new_lock_ctx ( struct xml_ctx * ctx , int tag_closed )
2005-11-05 01:22:31 +03:00
{
2006-03-08 03:13:20 +03:00
struct remote_lock * lock = ( struct remote_lock * ) ctx - > userData ;
use a hash of the lock token as the suffix for PUT/MOVE
After 753bc91 ("Remove the requirement opaquelocktoken uri scheme"),
lock tokens are in the URI forms in which they are received from the
server, eg. 'opaquelocktoken:', 'urn:uuid:'.
However, "start_put" (and consequently "start_move"), which attempts to
create a unique temporary file using the UUID of the lock token,
inadvertently uses the lock token in its URI form. These file
operations on the server may not be successful (specifically, in
Windows), due to the colon ':' character from the URI form of the lock
token in the file path.
This patch uses a hash of the lock token instead, guaranteeing only
"safe" characters (a-f, 0-9) are used in the file path.
The token's hash is generated when the lock token is received from the
server in handle_new_lock_ctx, minimizing the number of times of
hashing.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-14 12:52:14 +03:00
git_SHA_CTX sha_ctx ;
unsigned char lock_token_sha1 [ 20 ] ;
2005-11-18 22:03:18 +03:00
if ( tag_closed & & ctx - > cdata ) {
if ( ! strcmp ( ctx - > name , DAV_ACTIVELOCK_OWNER ) ) {
2014-06-20 01:19:43 +04:00
lock - > owner = xstrdup ( ctx - > cdata ) ;
2005-11-18 22:03:18 +03:00
} else if ( ! strcmp ( ctx - > name , DAV_ACTIVELOCK_TIMEOUT ) ) {
use skip_prefix to avoid magic numbers
It's a common idiom to match a prefix and then skip past it
with a magic number, like:
if (starts_with(foo, "bar"))
foo += 3;
This is easy to get wrong, since you have to count the
prefix string yourself, and there's no compiler check if the
string changes. We can use skip_prefix to avoid the magic
numbers here.
Note that some of these conversions could be much shorter.
For example:
if (starts_with(arg, "--foo=")) {
bar = arg + 6;
continue;
}
could become:
if (skip_prefix(arg, "--foo=", &bar))
continue;
However, I have left it as:
if (skip_prefix(arg, "--foo=", &v)) {
bar = v;
continue;
}
to visually match nearby cases which need to actually
process the string. Like:
if (skip_prefix(arg, "--foo=", &v)) {
bar = atoi(v);
continue;
}
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-18 23:47:50 +04:00
const char * arg ;
if ( skip_prefix ( ctx - > cdata , " Second- " , & arg ) )
lock - > timeout = strtol ( arg , NULL , 10 ) ;
2005-11-18 22:03:18 +03:00
} else if ( ! strcmp ( ctx - > name , DAV_ACTIVELOCK_TOKEN ) ) {
2014-06-20 01:19:43 +04:00
lock - > token = xstrdup ( ctx - > cdata ) ;
use a hash of the lock token as the suffix for PUT/MOVE
After 753bc91 ("Remove the requirement opaquelocktoken uri scheme"),
lock tokens are in the URI forms in which they are received from the
server, eg. 'opaquelocktoken:', 'urn:uuid:'.
However, "start_put" (and consequently "start_move"), which attempts to
create a unique temporary file using the UUID of the lock token,
inadvertently uses the lock token in its URI form. These file
operations on the server may not be successful (specifically, in
Windows), due to the colon ':' character from the URI form of the lock
token in the file path.
This patch uses a hash of the lock token instead, guaranteeing only
"safe" characters (a-f, 0-9) are used in the file path.
The token's hash is generated when the lock token is received from the
server in handle_new_lock_ctx, minimizing the number of times of
hashing.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-02-14 12:52:14 +03:00
git_SHA1_Init ( & sha_ctx ) ;
git_SHA1_Update ( & sha_ctx , lock - > token , strlen ( lock - > token ) ) ;
git_SHA1_Final ( lock_token_sha1 , & sha_ctx ) ;
lock - > tmpfile_suffix [ 0 ] = ' _ ' ;
memcpy ( lock - > tmpfile_suffix + 1 , sha1_to_hex ( lock_token_sha1 ) , 40 ) ;
2005-11-18 22:03:18 +03:00
}
2005-11-05 01:22:31 +03:00
}
}
2011-05-03 19:47:28 +04:00
static void one_remote_ref ( const char * refname ) ;
2006-03-08 03:13:20 +03:00
2005-11-05 01:22:31 +03:00
static void
2005-11-18 22:03:18 +03:00
xml_start_tag ( void * userData , const char * name , const char * * atts )
2005-11-05 01:22:31 +03:00
{
2005-11-18 22:03:18 +03:00
struct xml_ctx * ctx = ( struct xml_ctx * ) userData ;
2006-04-11 20:37:58 +04:00
const char * c = strchr ( name , ' : ' ) ;
2015-09-25 00:06:58 +03:00
int old_namelen , new_len ;
2005-11-18 22:03:18 +03:00
if ( c = = NULL )
c = name ;
else
c + + ;
2015-09-25 00:06:58 +03:00
old_namelen = strlen ( ctx - > name ) ;
new_len = old_namelen + strlen ( c ) + 2 ;
2005-11-18 22:03:18 +03:00
if ( new_len > ctx - > len ) {
ctx - > name = xrealloc ( ctx - > name , new_len ) ;
ctx - > len = new_len ;
2005-11-05 01:22:31 +03:00
}
2015-09-25 00:06:58 +03:00
xsnprintf ( ctx - > name + old_namelen , ctx - > len - old_namelen , " .%s " , c ) ;
2005-11-05 01:22:31 +03:00
2006-08-28 08:19:39 +04:00
free ( ctx - > cdata ) ;
ctx - > cdata = NULL ;
2005-11-18 22:03:18 +03:00
ctx - > userFunc ( ctx , 0 ) ;
2005-11-05 01:22:31 +03:00
}
2005-11-02 22:19:24 +03:00
static void
2005-11-18 22:03:18 +03:00
xml_end_tag ( void * userData , const char * name )
2005-11-02 22:19:24 +03:00
{
2005-11-18 22:03:18 +03:00
struct xml_ctx * ctx = ( struct xml_ctx * ) userData ;
2006-04-11 20:37:58 +04:00
const char * c = strchr ( name , ' : ' ) ;
2005-11-18 22:03:18 +03:00
char * ep ;
2005-11-02 22:19:24 +03:00
2005-11-18 22:03:18 +03:00
ctx - > userFunc ( ctx , 1 ) ;
if ( c = = NULL )
c = name ;
else
c + + ;
ep = ctx - > name + strlen ( ctx - > name ) - strlen ( c ) - 1 ;
* ep = 0 ;
2005-11-02 22:19:24 +03:00
}
static void
2005-11-18 22:03:18 +03:00
xml_cdata ( void * userData , const XML_Char * s , int len )
2005-11-02 22:19:24 +03:00
{
2005-11-18 22:03:18 +03:00
struct xml_ctx * ctx = ( struct xml_ctx * ) userData ;
2006-08-28 08:19:39 +04:00
free ( ctx - > cdata ) ;
2007-09-16 02:32:36 +04:00
ctx - > cdata = xmemdupz ( s , len ) ;
2005-11-02 22:19:24 +03:00
}
2006-06-28 13:04:39 +04:00
static struct remote_lock * lock_remote ( const char * path , long timeout )
2005-11-02 22:19:24 +03:00
{
struct active_request_slot * slot ;
2006-03-11 07:18:01 +03:00
struct slot_results results ;
2007-12-09 22:30:59 +03:00
struct buffer out_buffer = { STRBUF_INIT , 0 } ;
struct strbuf in_buffer = STRBUF_INIT ;
2005-11-02 22:19:24 +03:00
char * url ;
2005-11-05 01:22:25 +03:00
char * ep ;
2005-11-02 22:19:24 +03:00
char timeout_header [ 25 ] ;
2006-03-11 07:18:12 +03:00
struct remote_lock * lock = NULL ;
2016-04-27 15:20:37 +03:00
struct curl_slist * dav_headers = http_copy_default_headers ( ) ;
2005-11-18 22:03:18 +03:00
struct xml_ctx ctx ;
2009-04-10 02:25:37 +04:00
char * escaped ;
2005-11-02 22:19:24 +03:00
2014-06-20 01:24:33 +04:00
url = xstrfmt ( " %s%s " , repo - > url , path ) ;
2006-03-08 03:13:20 +03:00
2005-11-05 01:22:25 +03:00
/* Make sure leading directories exist for the remote ref */
2009-03-19 02:43:53 +03:00
ep = strchr ( url + strlen ( repo - > url ) + 1 , ' / ' ) ;
2005-11-05 01:22:25 +03:00
while ( ep ) {
2009-01-17 18:11:51 +03:00
char saved_character = ep [ 1 ] ;
ep [ 1 ] = ' \0 ' ;
2005-11-05 01:22:25 +03:00
slot = get_active_slot ( ) ;
2006-03-11 07:18:01 +03:00
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http_get ( slot - > curl , url , DAV_MKCOL ) ;
2005-11-05 01:22:25 +03:00
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
2006-03-11 07:18:01 +03:00
if ( results . curl_result ! = CURLE_OK & &
results . http_code ! = 405 ) {
2005-11-05 01:22:25 +03:00
fprintf ( stderr ,
" Unable to create branch path %s \n " ,
url ) ;
free ( url ) ;
return NULL ;
}
} else {
2006-03-11 07:18:33 +03:00
fprintf ( stderr , " Unable to start MKCOL request \n " ) ;
2005-11-05 01:22:25 +03:00
free ( url ) ;
return NULL ;
}
2009-01-17 18:11:51 +03:00
ep [ 1 ] = saved_character ;
2005-11-05 01:22:25 +03:00
ep = strchr ( ep + 1 , ' / ' ) ;
}
2012-05-22 03:09:47 +04:00
escaped = xml_entities ( ident_default_email ( ) ) ;
2009-04-10 02:25:37 +04:00
strbuf_addf ( & out_buffer . buf , LOCK_REQUEST , escaped ) ;
free ( escaped ) ;
2005-11-05 01:22:31 +03:00
2015-09-25 00:06:08 +03:00
xsnprintf ( timeout_header , sizeof ( timeout_header ) , " Timeout: Second-%ld " , timeout ) ;
2005-11-02 22:19:24 +03:00
dav_headers = curl_slist_append ( dav_headers , timeout_header ) ;
dav_headers = curl_slist_append ( dav_headers , " Content-Type: text/xml " ) ;
slot = get_active_slot ( ) ;
2006-03-11 07:18:01 +03:00
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http ( slot - > curl , url , DAV_LOCK , & out_buffer , fwrite_buffer ) ;
2005-11-02 22:19:24 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
2011-05-03 19:47:29 +04:00
curl_easy_setopt ( slot - > curl , CURLOPT_FILE , & in_buffer ) ;
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
lock = xcalloc ( 1 , sizeof ( * lock ) ) ;
lock - > timeout = - 1 ;
2005-11-18 22:03:18 +03:00
2005-11-02 22:19:24 +03:00
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
2006-03-11 07:18:01 +03:00
if ( results . curl_result = = CURLE_OK ) {
2007-12-12 01:50:21 +03:00
XML_Parser parser = XML_ParserCreate ( NULL ) ;
enum XML_Status result ;
2005-11-18 22:03:18 +03:00
ctx . name = xcalloc ( 10 , 1 ) ;
ctx . len = 0 ;
ctx . cdata = NULL ;
ctx . userFunc = handle_new_lock_ctx ;
2006-03-08 03:13:20 +03:00
ctx . userData = lock ;
2005-11-18 22:03:18 +03:00
XML_SetUserData ( parser , & ctx ) ;
XML_SetElementHandler ( parser , xml_start_tag ,
xml_end_tag ) ;
XML_SetCharacterDataHandler ( parser , xml_cdata ) ;
2007-12-09 22:30:59 +03:00
result = XML_Parse ( parser , in_buffer . buf ,
in_buffer . len , 1 ) ;
2005-11-18 22:03:18 +03:00
free ( ctx . name ) ;
if ( result ! = XML_STATUS_OK ) {
fprintf ( stderr , " XML error: %s \n " ,
XML_ErrorString (
XML_GetErrorCode ( parser ) ) ) ;
2006-03-08 03:13:20 +03:00
lock - > timeout = - 1 ;
2005-11-18 22:03:18 +03:00
}
2007-12-12 01:50:21 +03:00
XML_ParserFree ( parser ) ;
2005-11-02 22:19:24 +03:00
}
} else {
2006-03-11 07:18:33 +03:00
fprintf ( stderr , " Unable to start LOCK request \n " ) ;
2005-11-02 22:19:24 +03:00
}
2005-11-18 22:03:18 +03:00
curl_slist_free_all ( dav_headers ) ;
2007-12-09 22:30:59 +03:00
strbuf_release ( & out_buffer . buf ) ;
strbuf_release ( & in_buffer ) ;
2005-11-05 01:22:31 +03:00
2006-03-08 03:13:20 +03:00
if ( lock - > token = = NULL | | lock - > timeout < = 0 ) {
Avoid unnecessary "if-before-free" tests.
This change removes all obvious useless if-before-free tests.
E.g., it replaces code like this:
if (some_expression)
free (some_expression);
with the now-equivalent:
free (some_expression);
It is equivalent not just because POSIX has required free(NULL)
to work for a long time, but simply because it has worked for
so long that no reasonable porting target fails the test.
Here's some evidence from nearly 1.5 years ago:
http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html
FYI, the change below was prepared by running the following:
git ls-files -z | xargs -0 \
perl -0x3b -pi -e \
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(free\s*\(\s*\1\s*\))/$2/s'
Note however, that it doesn't handle brace-enclosed blocks like
"if (x) { free (x); }". But that's ok, since there were none like
that in git sources.
Beware: if you do use the above snippet, note that it can
produce syntactically invalid C code. That happens when the
affected "if"-statement has a matching "else".
E.g., it would transform this
if (x)
free (x);
else
foo ();
into this:
free (x);
else
foo ();
There were none of those here, either.
If you're interested in automating detection of the useless
tests, you might like the useless-if-before-free script in gnulib:
[it *does* detect brace-enclosed free statements, and has a --name=S
option to make it detect free-like functions with different names]
http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=build-aux/useless-if-before-free
Addendum:
Remove one more (in imap-send.c), spotted by Jean-Luc Herren <jlh@gmx.ch>.
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-31 20:26:32 +03:00
free ( lock - > token ) ;
free ( lock - > owner ) ;
2005-11-05 01:22:35 +03:00
free ( url ) ;
2006-03-08 03:13:20 +03:00
free ( lock ) ;
lock = NULL ;
2005-11-18 22:03:18 +03:00
} else {
2006-03-08 03:13:20 +03:00
lock - > url = url ;
lock - > start_time = time ( NULL ) ;
2009-03-19 02:43:53 +03:00
lock - > next = repo - > locks ;
repo - > locks = lock ;
2005-11-05 01:22:31 +03:00
}
2006-03-08 03:13:20 +03:00
return lock ;
2005-11-02 22:19:24 +03:00
}
2006-03-08 03:13:20 +03:00
static int unlock_remote ( struct remote_lock * lock )
2005-11-02 22:19:24 +03:00
{
struct active_request_slot * slot ;
2006-03-11 07:18:01 +03:00
struct slot_results results ;
2009-03-19 02:43:53 +03:00
struct remote_lock * prev = repo - > locks ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
struct curl_slist * dav_headers ;
2005-11-02 22:19:24 +03:00
int rc = 0 ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
dav_headers = get_dav_token_headers ( lock , DAV_HEADER_LOCK ) ;
2005-11-02 22:19:24 +03:00
slot = get_active_slot ( ) ;
2006-03-11 07:18:01 +03:00
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http_get ( slot - > curl , lock - > url , DAV_UNLOCK ) ;
2005-11-02 22:19:24 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
2006-03-11 07:18:01 +03:00
if ( results . curl_result = = CURLE_OK )
2005-11-02 22:19:24 +03:00
rc = 1 ;
else
2006-03-11 07:18:12 +03:00
fprintf ( stderr , " UNLOCK HTTP error %ld \n " ,
2006-03-11 07:18:01 +03:00
results . http_code ) ;
2005-11-02 22:19:24 +03:00
} else {
2006-03-11 07:18:12 +03:00
fprintf ( stderr , " Unable to start UNLOCK request \n " ) ;
2005-11-02 22:19:24 +03:00
}
curl_slist_free_all ( dav_headers ) ;
2005-11-05 01:22:35 +03:00
2009-03-19 02:43:53 +03:00
if ( repo - > locks = = lock ) {
repo - > locks = lock - > next ;
2006-03-11 07:18:12 +03:00
} else {
while ( prev & & prev - > next ! = lock )
prev = prev - > next ;
if ( prev )
prev - > next = prev - > next - > next ;
}
Avoid unnecessary "if-before-free" tests.
This change removes all obvious useless if-before-free tests.
E.g., it replaces code like this:
if (some_expression)
free (some_expression);
with the now-equivalent:
free (some_expression);
It is equivalent not just because POSIX has required free(NULL)
to work for a long time, but simply because it has worked for
so long that no reasonable porting target fails the test.
Here's some evidence from nearly 1.5 years ago:
http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html
FYI, the change below was prepared by running the following:
git ls-files -z | xargs -0 \
perl -0x3b -pi -e \
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(free\s*\(\s*\1\s*\))/$2/s'
Note however, that it doesn't handle brace-enclosed blocks like
"if (x) { free (x); }". But that's ok, since there were none like
that in git sources.
Beware: if you do use the above snippet, note that it can
produce syntactically invalid C code. That happens when the
affected "if"-statement has a matching "else".
E.g., it would transform this
if (x)
free (x);
else
foo ();
into this:
free (x);
else
foo ();
There were none of those here, either.
If you're interested in automating detection of the useless
tests, you might like the useless-if-before-free script in gnulib:
[it *does* detect brace-enclosed free statements, and has a --name=S
option to make it detect free-like functions with different names]
http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=build-aux/useless-if-before-free
Addendum:
Remove one more (in imap-send.c), spotted by Jean-Luc Herren <jlh@gmx.ch>.
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-31 20:26:32 +03:00
free ( lock - > owner ) ;
2006-03-11 07:18:12 +03:00
free ( lock - > url ) ;
free ( lock - > token ) ;
free ( lock ) ;
2005-11-02 22:19:24 +03:00
return rc ;
}
2008-05-25 22:27:44 +04:00
static void remove_locks ( void )
{
2009-03-19 02:43:53 +03:00
struct remote_lock * lock = repo - > locks ;
2008-05-25 22:27:44 +04:00
fprintf ( stderr , " Removing remote locks... \n " ) ;
while ( lock ) {
2009-05-24 17:16:49 +04:00
struct remote_lock * next = lock - > next ;
2008-05-25 22:27:44 +04:00
unlock_remote ( lock ) ;
2009-05-24 17:16:49 +04:00
lock = next ;
2008-05-25 22:27:44 +04:00
}
}
static void remove_locks_on_signal ( int signo )
{
remove_locks ( ) ;
chain kill signals for cleanup functions
If a piece of code wanted to do some cleanup before exiting
(e.g., cleaning up a lockfile or a tempfile), our usual
strategy was to install a signal handler that did something
like this:
do_cleanup(); /* actual work */
signal(signo, SIG_DFL); /* restore previous behavior */
raise(signo); /* deliver signal, killing ourselves */
For a single handler, this works fine. However, if we want
to clean up two _different_ things, we run into a problem.
The most recently installed handler will run, but when it
removes itself as a handler, it doesn't put back the first
handler.
This patch introduces sigchain, a tiny library for handling
a stack of signal handlers. You sigchain_push each handler,
and use sigchain_pop to restore whoever was before you in
the stack.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-22 09:02:35 +03:00
sigchain_pop ( signo ) ;
2008-05-25 22:27:44 +04:00
raise ( signo ) ;
}
2006-03-11 07:18:08 +03:00
static void remote_ls ( const char * path , int flags ,
void ( * userFunc ) ( struct remote_ls_ctx * ls ) ,
void * userData ) ;
2006-03-08 03:13:20 +03:00
2014-06-20 01:58:10 +04:00
/* extract hex from sharded "xx/x{40}" filename */
static int get_sha1_hex_from_objpath ( const char * path , unsigned char * sha1 )
{
char hex [ 40 ] ;
if ( strlen ( path ) ! = 41 )
return - 1 ;
memcpy ( hex , path , 2 ) ;
path + = 2 ;
path + + ; /* skip '/' */
memcpy ( hex , path , 38 ) ;
return get_sha1_hex ( hex , sha1 ) ;
}
2006-03-11 07:18:08 +03:00
static void process_ls_object ( struct remote_ls_ctx * ls )
{
unsigned int * parent = ( unsigned int * ) ls - > userData ;
2014-06-20 01:58:10 +04:00
const char * path = ls - > dentry_name ;
unsigned char sha1 [ 20 ] ;
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:08 +03:00
if ( ! strcmp ( ls - > path , ls - > dentry_name ) & & ( ls - > flags & IS_DIR ) ) {
remote_dir_exists [ * parent ] = 1 ;
return ;
}
2006-03-08 03:13:20 +03:00
2014-06-20 01:58:10 +04:00
if ( ! skip_prefix ( path , " objects/ " , & path ) | |
get_sha1_hex_from_objpath ( path , sha1 ) )
2006-03-11 07:18:08 +03:00
return ;
2014-06-20 01:58:10 +04:00
one_remote_object ( sha1 ) ;
2006-03-11 07:18:08 +03:00
}
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:08 +03:00
static void process_ls_ref ( struct remote_ls_ctx * ls )
{
if ( ! strcmp ( ls - > path , ls - > dentry_name ) & & ( ls - > dentry_flags & IS_DIR ) ) {
fprintf ( stderr , " %s \n " , ls - > dentry_name ) ;
return ;
}
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:08 +03:00
if ( ! ( ls - > dentry_flags & IS_DIR ) )
one_remote_ref ( ls - > dentry_name ) ;
}
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:08 +03:00
static void handle_remote_ls_ctx ( struct xml_ctx * ctx , int tag_closed )
{
struct remote_ls_ctx * ls = ( struct remote_ls_ctx * ) ctx - > userData ;
2006-03-08 03:13:20 +03:00
2006-03-11 07:18:08 +03:00
if ( tag_closed ) {
if ( ! strcmp ( ctx - > name , DAV_PROPFIND_RESP ) & & ls - > dentry_name ) {
if ( ls - > dentry_flags & IS_DIR ) {
2010-11-25 11:21:07 +03:00
/* ensure collection names end with slash */
str_end_url_with_slash ( ls - > dentry_name , & ls - > dentry_name ) ;
2006-03-11 07:18:08 +03:00
if ( ls - > flags & PROCESS_DIRS ) {
ls - > userFunc ( ls ) ;
}
if ( strcmp ( ls - > dentry_name , ls - > path ) & &
ls - > flags & RECURSIVE ) {
remote_ls ( ls - > dentry_name ,
ls - > flags ,
ls - > userFunc ,
ls - > userData ) ;
}
} else if ( ls - > flags & PROCESS_FILES ) {
ls - > userFunc ( ls ) ;
2006-03-08 03:13:20 +03:00
}
2006-03-11 07:18:08 +03:00
} else if ( ! strcmp ( ctx - > name , DAV_PROPFIND_NAME ) & & ctx - > cdata ) {
2008-12-23 11:31:15 +03:00
char * path = ctx - > cdata ;
if ( * ctx - > cdata = = ' h ' ) {
path = strstr ( path , " // " ) ;
if ( path ) {
path = strchr ( path + 2 , ' / ' ) ;
}
}
if ( path ) {
2010-11-25 11:21:08 +03:00
const char * url = repo - > url ;
if ( repo - > path )
url = repo - > path ;
if ( strncmp ( path , url , repo - > path_len ) )
2012-04-30 04:28:45 +04:00
error ( " Parsed path '%s' does not match url: '%s' " ,
2010-11-25 11:21:08 +03:00
path , url ) ;
else {
path + = repo - > path_len ;
ls - > dentry_name = xstrdup ( path ) ;
}
2008-12-23 11:31:15 +03:00
}
2006-03-11 07:18:08 +03:00
} else if ( ! strcmp ( ctx - > name , DAV_PROPFIND_COLLECTION ) ) {
ls - > dentry_flags | = IS_DIR ;
2006-03-08 03:13:20 +03:00
}
2006-03-11 07:18:08 +03:00
} else if ( ! strcmp ( ctx - > name , DAV_PROPFIND_RESP ) ) {
2006-08-28 08:19:39 +04:00
free ( ls - > dentry_name ) ;
2006-03-11 07:18:08 +03:00
ls - > dentry_name = NULL ;
ls - > dentry_flags = 0 ;
2006-03-08 03:13:20 +03:00
}
}
2009-01-17 18:36:26 +03:00
/*
* NEEDSWORK : remote_ls ( ) ignores info / refs on the remote side . But it
* should _only_ heed the information from that file , instead of trying to
* determine the refs from the remote file system ( badly : it does not even
* know about packed - refs ) .
*/
2006-03-11 07:18:08 +03:00
static void remote_ls ( const char * path , int flags ,
void ( * userFunc ) ( struct remote_ls_ctx * ls ) ,
void * userData )
2006-03-08 03:13:20 +03:00
{
2014-06-20 01:24:33 +04:00
char * url = xstrfmt ( " %s%s " , repo - > url , path ) ;
2006-03-08 03:13:20 +03:00
struct active_request_slot * slot ;
2006-03-11 07:18:01 +03:00
struct slot_results results ;
2007-12-09 22:30:59 +03:00
struct strbuf in_buffer = STRBUF_INIT ;
struct buffer out_buffer = { STRBUF_INIT , 0 } ;
2016-04-27 15:20:37 +03:00
struct curl_slist * dav_headers = http_copy_default_headers ( ) ;
2006-03-08 03:13:20 +03:00
struct xml_ctx ctx ;
2006-03-11 07:18:08 +03:00
struct remote_ls_ctx ls ;
ls . flags = flags ;
2006-09-02 08:16:31 +04:00
ls . path = xstrdup ( path ) ;
2006-03-11 07:18:08 +03:00
ls . dentry_name = NULL ;
ls . dentry_flags = 0 ;
ls . userData = userData ;
ls . userFunc = userFunc ;
2006-03-08 03:13:20 +03:00
2016-07-30 20:36:23 +03:00
strbuf_addstr ( & out_buffer . buf , PROPFIND_ALL_REQUEST ) ;
2006-03-08 03:13:20 +03:00
dav_headers = curl_slist_append ( dav_headers , " Depth: 1 " ) ;
dav_headers = curl_slist_append ( dav_headers , " Content-Type: text/xml " ) ;
slot = get_active_slot ( ) ;
2006-03-11 07:18:01 +03:00
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http ( slot - > curl , url , DAV_PROPFIND ,
& out_buffer , fwrite_buffer ) ;
2006-03-08 03:13:20 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
2011-05-03 19:47:29 +04:00
curl_easy_setopt ( slot - > curl , CURLOPT_FILE , & in_buffer ) ;
2006-03-08 03:13:20 +03:00
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
2006-03-11 07:18:01 +03:00
if ( results . curl_result = = CURLE_OK ) {
2007-12-12 01:50:21 +03:00
XML_Parser parser = XML_ParserCreate ( NULL ) ;
enum XML_Status result ;
2006-03-08 03:13:20 +03:00
ctx . name = xcalloc ( 10 , 1 ) ;
ctx . len = 0 ;
ctx . cdata = NULL ;
2006-03-11 07:18:08 +03:00
ctx . userFunc = handle_remote_ls_ctx ;
ctx . userData = & ls ;
2006-03-08 03:13:20 +03:00
XML_SetUserData ( parser , & ctx ) ;
XML_SetElementHandler ( parser , xml_start_tag ,
xml_end_tag ) ;
XML_SetCharacterDataHandler ( parser , xml_cdata ) ;
2007-12-09 22:30:59 +03:00
result = XML_Parse ( parser , in_buffer . buf ,
in_buffer . len , 1 ) ;
2006-03-08 03:13:20 +03:00
free ( ctx . name ) ;
if ( result ! = XML_STATUS_OK ) {
fprintf ( stderr , " XML error: %s \n " ,
XML_ErrorString (
XML_GetErrorCode ( parser ) ) ) ;
}
2007-12-12 01:50:21 +03:00
XML_ParserFree ( parser ) ;
2006-03-08 03:13:20 +03:00
}
} else {
2006-03-11 07:18:08 +03:00
fprintf ( stderr , " Unable to start PROPFIND request \n " ) ;
2006-03-08 03:13:20 +03:00
}
2006-03-11 07:18:08 +03:00
free ( ls . path ) ;
2006-03-08 03:13:20 +03:00
free ( url ) ;
2007-12-09 22:30:59 +03:00
strbuf_release ( & out_buffer . buf ) ;
strbuf_release ( & in_buffer ) ;
2006-03-08 03:13:20 +03:00
curl_slist_free_all ( dav_headers ) ;
}
2006-03-11 07:18:08 +03:00
static void get_remote_object_list ( unsigned char parent )
{
char path [ ] = " objects/XX/ " ;
static const char hex [ ] = " 0123456789abcdef " ;
unsigned int val = parent ;
path [ 8 ] = hex [ val > > 4 ] ;
path [ 9 ] = hex [ val & 0xf ] ;
remote_dir_exists [ val ] = 0 ;
remote_ls ( path , ( PROCESS_FILES | PROCESS_DIRS ) ,
process_ls_object , & val ) ;
}
2005-11-18 22:03:18 +03:00
static int locking_available ( void )
2005-11-02 22:19:24 +03:00
{
struct active_request_slot * slot ;
2006-03-11 07:18:01 +03:00
struct slot_results results ;
2007-12-09 22:30:59 +03:00
struct strbuf in_buffer = STRBUF_INIT ;
struct buffer out_buffer = { STRBUF_INIT , 0 } ;
2016-04-27 15:20:37 +03:00
struct curl_slist * dav_headers = http_copy_default_headers ( ) ;
2005-11-18 22:03:18 +03:00
struct xml_ctx ctx ;
int lock_flags = 0 ;
2009-04-10 02:25:37 +04:00
char * escaped ;
2005-11-02 22:19:24 +03:00
2009-04-10 02:25:37 +04:00
escaped = xml_entities ( repo - > url ) ;
strbuf_addf ( & out_buffer . buf , PROPFIND_SUPPORTEDLOCK_REQUEST , escaped ) ;
free ( escaped ) ;
2005-11-02 22:19:24 +03:00
dav_headers = curl_slist_append ( dav_headers , " Depth: 0 " ) ;
dav_headers = curl_slist_append ( dav_headers , " Content-Type: text/xml " ) ;
2006-03-11 07:18:01 +03:00
2005-11-02 22:19:24 +03:00
slot = get_active_slot ( ) ;
2006-03-11 07:18:01 +03:00
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http ( slot - > curl , repo - > url , DAV_PROPFIND ,
& out_buffer , fwrite_buffer ) ;
2005-11-02 22:19:24 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
2011-05-03 19:47:29 +04:00
curl_easy_setopt ( slot - > curl , CURLOPT_FILE , & in_buffer ) ;
2005-11-02 22:19:24 +03:00
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
2006-03-11 07:18:01 +03:00
if ( results . curl_result = = CURLE_OK ) {
2007-12-12 01:50:21 +03:00
XML_Parser parser = XML_ParserCreate ( NULL ) ;
enum XML_Status result ;
2005-11-18 22:03:18 +03:00
ctx . name = xcalloc ( 10 , 1 ) ;
ctx . len = 0 ;
ctx . cdata = NULL ;
ctx . userFunc = handle_lockprop_ctx ;
ctx . userData = & lock_flags ;
XML_SetUserData ( parser , & ctx ) ;
XML_SetElementHandler ( parser , xml_start_tag ,
xml_end_tag ) ;
2007-12-09 22:30:59 +03:00
result = XML_Parse ( parser , in_buffer . buf ,
in_buffer . len , 1 ) ;
2005-11-18 22:03:18 +03:00
free ( ctx . name ) ;
if ( result ! = XML_STATUS_OK ) {
fprintf ( stderr , " XML error: %s \n " ,
XML_ErrorString (
XML_GetErrorCode ( parser ) ) ) ;
lock_flags = 0 ;
}
2007-12-12 01:50:21 +03:00
XML_ParserFree ( parser ) ;
2008-01-21 02:00:54 +03:00
if ( ! lock_flags )
2009-03-24 04:09:09 +03:00
error ( " no DAV locking support on %s " ,
2009-03-19 02:43:53 +03:00
repo - > url ) ;
2008-01-21 02:00:54 +03:00
} else {
error ( " Cannot access URL %s, return code %d " ,
2009-03-19 02:43:53 +03:00
repo - > url , results . curl_result ) ;
2008-01-21 02:00:54 +03:00
lock_flags = 0 ;
2005-11-02 22:19:24 +03:00
}
} else {
2009-03-19 02:43:53 +03:00
error ( " Unable to start PROPFIND request on %s " , repo - > url ) ;
2005-11-02 22:19:24 +03:00
}
2007-12-09 22:30:59 +03:00
strbuf_release ( & out_buffer . buf ) ;
strbuf_release ( & in_buffer ) ;
2005-11-18 22:03:18 +03:00
curl_slist_free_all ( dav_headers ) ;
return lock_flags ;
2005-11-02 22:19:24 +03:00
}
2006-08-23 14:39:12 +04:00
static struct object_list * * add_one_object ( struct object * obj , struct object_list * * p )
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
{
struct object_list * entry = xmalloc ( sizeof ( struct object_list ) ) ;
entry - > item = obj ;
entry - > next = * p ;
* p = entry ;
return & entry - > next ;
}
2006-03-08 03:13:20 +03:00
static struct object_list * * process_blob ( struct blob * blob ,
2016-02-12 01:23:48 +03:00
struct object_list * * p )
2005-11-02 22:19:24 +03:00
{
2006-03-08 03:13:20 +03:00
struct object * obj = & blob - > object ;
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
obj - > flags | = LOCAL ;
if ( obj - > flags & ( UNINTERESTING | SEEN ) )
return p ;
obj - > flags | = SEEN ;
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
return add_one_object ( obj , p ) ;
2006-03-08 03:13:20 +03:00
}
static struct object_list * * process_tree ( struct tree * tree ,
2016-02-12 01:23:48 +03:00
struct object_list * * p )
2006-03-08 03:13:20 +03:00
{
struct object * obj = & tree - > object ;
2006-05-29 23:18:33 +04:00
struct tree_desc desc ;
tree_entry(): new tree-walking helper function
This adds a "tree_entry()" function that combines the common operation of
doing a "tree_entry_extract()" + "update_tree_entry()".
It also has a simplified calling convention, designed for simple loops
that traverse over a whole tree: the arguments are pointers to the tree
descriptor and a name_entry structure to fill in, and it returns a boolean
"true" if there was an entry left to be gotten in the tree.
This allows tree traversal with
struct tree_desc desc;
struct name_entry entry;
desc.buf = tree->buffer;
desc.size = tree->size;
while (tree_entry(&desc, &entry) {
... use "entry.{path, sha1, mode, pathlen}" ...
}
which is not only shorter than writing it out in full, it's hopefully less
error prone too.
[ It's actually a tad faster too - we don't need to recalculate the entry
pathlength in both extract and update, but need to do it only once.
Also, some callers can avoid doing a "strlen()" on the result, since
it's returned as part of the name_entry structure.
However, by now we're talking just 1% speedup on "git-rev-list --objects
--all", and we're definitely at the point where tree walking is no
longer the issue any more. ]
NOTE! Not everybody wants to use this new helper function, since some of
the tree walkers very much on purpose do the descriptor update separately
from the entry extraction. So the "extract + update" sequence still
remains as the core sequence, this is just a simplified interface.
We should probably add a silly two-line inline helper function for
initializing the descriptor from the "struct tree" too, just to cut down
on the noise from that common "desc" initializer.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-05-30 20:45:45 +04:00
struct name_entry entry ;
2006-03-08 03:13:20 +03:00
obj - > flags | = LOCAL ;
if ( obj - > flags & ( UNINTERESTING | SEEN ) )
return p ;
if ( parse_tree ( tree ) < 0 )
2015-11-10 05:22:28 +03:00
die ( " bad tree object %s " , oid_to_hex ( & obj - > oid ) ) ;
2006-03-08 03:13:20 +03:00
obj - > flags | = SEEN ;
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
p = add_one_object ( obj , p ) ;
2006-05-29 23:18:33 +04:00
2007-03-21 20:08:25 +03:00
init_tree_desc ( & desc , tree - > buffer , tree - > size ) ;
2006-05-29 23:18:33 +04:00
2008-02-15 02:32:32 +03:00
while ( tree_entry ( & desc , & entry ) )
switch ( object_type ( entry . mode ) ) {
case OBJ_TREE :
2016-04-18 02:10:39 +03:00
p = process_tree ( lookup_tree ( entry . oid - > hash ) , p ) ;
2008-02-15 02:32:32 +03:00
break ;
case OBJ_BLOB :
2016-04-18 02:10:39 +03:00
p = process_blob ( lookup_blob ( entry . oid - > hash ) , p ) ;
2008-02-15 02:32:32 +03:00
break ;
default :
/* Subproject commit - not in this repository */
break ;
}
2013-06-06 02:37:39 +04:00
free_tree_buffer ( tree ) ;
2006-03-08 03:13:20 +03:00
return p ;
2005-11-02 22:19:24 +03:00
}
2006-03-11 07:18:33 +03:00
static int get_delta ( struct rev_info * revs , struct remote_lock * lock )
2005-11-02 22:19:24 +03:00
{
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
int i ;
2005-11-02 22:19:24 +03:00
struct commit * commit ;
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
struct object_list * * p = & objects ;
2006-03-11 07:18:33 +03:00
int count = 0 ;
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
while ( ( commit = get_revision ( revs ) ) ! = NULL ) {
2016-02-12 01:23:48 +03:00
p = process_tree ( commit - > tree , p ) ;
2006-03-08 03:13:20 +03:00
commit - > object . flags | = LOCAL ;
if ( ! ( commit - > object . flags & UNINTERESTING ) )
2006-03-11 07:18:33 +03:00
count + = add_send_request ( & commit - > object , lock ) ;
2006-03-08 03:13:20 +03:00
}
2005-11-02 22:19:24 +03:00
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
for ( i = 0 ; i < revs - > pending . nr ; i + + ) {
struct object_array_entry * entry = revs - > pending . objects + i ;
struct object * obj = entry - > item ;
const char * name = entry - > name ;
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
if ( obj - > flags & ( UNINTERESTING | SEEN ) )
continue ;
2006-07-12 07:45:31 +04:00
if ( obj - > type = = OBJ_TAG ) {
2006-03-08 03:13:20 +03:00
obj - > flags | = SEEN ;
Add "named object array" concept
We've had this notion of a "object_list" for a long time, which eventually
grew a "name" member because some users (notably git-rev-list) wanted to
name each object as it is generated.
That object_list is great for some things, but it isn't all that wonderful
for others, and the "name" member is generally not used by everybody.
This patch splits the users of the object_list array up into two: the
traditional list users, who want the list-like format, and who don't
actually use or want the name. And another class of users that really used
the list as an extensible array, and generally wanted to name the objects.
The patch is fairly straightforward, but it's also biggish. Most of it
really just cleans things up: switching the revision parsing and listing
over to the array makes things like the builtin-diff usage much simpler
(we now see exactly how many members the array has, and we don't get the
objects reversed from the order they were on the command line).
One of the main reasons for doing this at all is that the malloc overhead
of the simple object list was actually pretty high, and the array is just
a lot denser. So this patch brings down memory usage by git-rev-list by
just under 3% (on top of all the other memory use optimizations) on the
mozilla archive.
It does add more lines than it removes, and more importantly, it adds a
whole new infrastructure for maintaining lists of objects, but on the
other hand, the new dynamic array code is pretty obvious. The change to
builtin-diff-tree.c shows a fairly good example of why an array interface
is sometimes more natural, and just much simpler for everybody.
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-06-20 04:42:35 +04:00
p = add_one_object ( obj , p ) ;
2006-03-08 03:13:20 +03:00
continue ;
2005-11-02 22:19:24 +03:00
}
2006-07-12 07:45:31 +04:00
if ( obj - > type = = OBJ_TREE ) {
2016-02-12 01:23:48 +03:00
p = process_tree ( ( struct tree * ) obj , p ) ;
2006-03-08 03:13:20 +03:00
continue ;
2005-11-02 22:19:24 +03:00
}
2006-07-12 07:45:31 +04:00
if ( obj - > type = = OBJ_BLOB ) {
2016-02-12 01:23:48 +03:00
p = process_blob ( ( struct blob * ) obj , p ) ;
2006-03-08 03:13:20 +03:00
continue ;
2005-11-02 22:19:24 +03:00
}
2015-11-10 05:22:28 +03:00
die ( " unknown pending object %s (%s) " , oid_to_hex ( & obj - > oid ) , name ) ;
2006-03-08 03:13:20 +03:00
}
while ( objects ) {
if ( ! ( objects - > item - > flags & UNINTERESTING ) )
2006-03-11 07:18:33 +03:00
count + = add_send_request ( objects - > item , lock ) ;
2006-03-08 03:13:20 +03:00
objects = objects - > next ;
2005-11-02 22:19:24 +03:00
}
2006-03-11 07:18:33 +03:00
return count ;
2005-11-02 22:19:24 +03:00
}
2006-03-08 03:13:20 +03:00
static int update_remote ( unsigned char * sha1 , struct remote_lock * lock )
2005-11-02 22:19:24 +03:00
{
struct active_request_slot * slot ;
2006-03-11 07:18:01 +03:00
struct slot_results results ;
2007-12-09 22:30:59 +03:00
struct buffer out_buffer = { STRBUF_INIT , 0 } ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
struct curl_slist * dav_headers ;
2005-11-02 22:19:24 +03:00
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
dav_headers = get_dav_token_headers ( lock , DAV_HEADER_IF ) ;
2005-11-02 22:19:24 +03:00
2007-12-09 22:30:59 +03:00
strbuf_addf ( & out_buffer . buf , " %s \n " , sha1_to_hex ( sha1 ) ) ;
2005-11-02 22:19:24 +03:00
slot = get_active_slot ( ) ;
2006-03-11 07:18:01 +03:00
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http ( slot - > curl , lock - > url , DAV_PUT ,
& out_buffer , fwrite_null ) ;
2005-11-02 22:19:24 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
2007-12-09 22:30:59 +03:00
strbuf_release ( & out_buffer . buf ) ;
2006-03-11 07:18:01 +03:00
if ( results . curl_result ! = CURLE_OK ) {
2005-11-02 22:19:24 +03:00
fprintf ( stderr ,
" PUT error: curl result=%d, HTTP code=%ld \n " ,
2006-03-11 07:18:01 +03:00
results . curl_result , results . http_code ) ;
2005-11-02 22:19:24 +03:00
/* We should attempt recovery? */
return 0 ;
}
} else {
2007-12-09 22:30:59 +03:00
strbuf_release ( & out_buffer . buf ) ;
2005-11-02 22:19:24 +03:00
fprintf ( stderr , " Unable to start PUT request \n " ) ;
return 0 ;
}
return 1 ;
}
2009-05-31 18:26:48 +04:00
static struct ref * remote_refs ;
2006-03-08 03:13:20 +03:00
2011-05-03 19:47:28 +04:00
static void one_remote_ref ( const char * refname )
2006-03-08 03:13:20 +03:00
{
struct ref * ref ;
2006-03-11 07:18:18 +03:00
struct object * obj ;
2006-03-08 03:13:20 +03:00
2008-10-18 12:44:18 +04:00
ref = alloc_ref ( refname ) ;
Make walker.fetch_ref() take a struct ref.
This simplifies a few things, makes a few things slightly more
complicated, but, more importantly, allows that, when struct ref can
represent a symref, http_fetch_ref() can return one.
Incidentally makes the string that http_fetch_ref() gets include "refs/"
(if appropriate), because that's how the name field of struct ref works.
As far as I can tell, the usage in walker:interpret_target() wouldn't have
worked previously, if it ever would have been used, which it wouldn't
(since the fetch process uses the hash instead of the name of the ref
there).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-26 23:53:09 +04:00
2009-03-19 02:43:53 +03:00
if ( http_fetch_ref ( repo - > url , ref ) ! = 0 ) {
2006-03-08 03:13:20 +03:00
fprintf ( stderr ,
" Unable to fetch ref %s from %s \n " ,
2009-03-19 02:43:53 +03:00
refname , repo - > url ) ;
Make walker.fetch_ref() take a struct ref.
This simplifies a few things, makes a few things slightly more
complicated, but, more importantly, allows that, when struct ref can
represent a symref, http_fetch_ref() can return one.
Incidentally makes the string that http_fetch_ref() gets include "refs/"
(if appropriate), because that's how the name field of struct ref works.
As far as I can tell, the usage in walker:interpret_target() wouldn't have
worked previously, if it ever would have been used, which it wouldn't
(since the fetch process uses the hash instead of the name of the ref
there).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-26 23:53:09 +04:00
free ( ref ) ;
2006-03-08 03:13:20 +03:00
return ;
}
2006-03-11 07:18:18 +03:00
/*
* Fetch a copy of the object if it doesn ' t exist locally - it
* may be required for updating server info later .
*/
2015-11-10 05:22:20 +03:00
if ( repo - > can_update_info_refs & & ! has_object_file ( & ref - > old_oid ) ) {
obj = lookup_unknown_object ( ref - > old_oid . hash ) ;
2017-03-18 01:12:31 +03:00
fprintf ( stderr , " fetch %s for %s \n " ,
oid_to_hex ( & ref - > old_oid ) , refname ) ;
add_fetch_request ( obj ) ;
2006-03-11 07:18:18 +03:00
}
2009-05-31 18:26:48 +04:00
ref - > next = remote_refs ;
remote_refs = ref ;
2006-03-08 03:13:20 +03:00
}
static void get_dav_remote_heads ( void )
{
2006-03-11 07:18:08 +03:00
remote_ls ( " refs/ " , ( PROCESS_FILES | PROCESS_DIRS | RECURSIVE ) , process_ls_ref , NULL ) ;
2006-03-08 03:13:20 +03:00
}
2006-03-11 07:18:18 +03:00
static void add_remote_info_ref ( struct remote_ls_ctx * ls )
{
2007-12-09 22:30:59 +03:00
struct strbuf * buf = ( struct strbuf * ) ls - > userData ;
2006-03-11 07:18:18 +03:00
struct object * o ;
Make walker.fetch_ref() take a struct ref.
This simplifies a few things, makes a few things slightly more
complicated, but, more importantly, allows that, when struct ref can
represent a symref, http_fetch_ref() can return one.
Incidentally makes the string that http_fetch_ref() gets include "refs/"
(if appropriate), because that's how the name field of struct ref works.
As far as I can tell, the usage in walker:interpret_target() wouldn't have
worked previously, if it ever would have been used, which it wouldn't
(since the fetch process uses the hash instead of the name of the ref
there).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-26 23:53:09 +04:00
struct ref * ref ;
2008-10-18 12:44:18 +04:00
ref = alloc_ref ( ls - > dentry_name ) ;
2006-03-11 07:18:18 +03:00
2009-03-19 02:43:53 +03:00
if ( http_fetch_ref ( repo - > url , ref ) ! = 0 ) {
2006-03-11 07:18:18 +03:00
fprintf ( stderr ,
" Unable to fetch ref %s from %s \n " ,
2009-03-19 02:43:53 +03:00
ls - > dentry_name , repo - > url ) ;
2006-03-11 07:18:18 +03:00
aborted = 1 ;
Make walker.fetch_ref() take a struct ref.
This simplifies a few things, makes a few things slightly more
complicated, but, more importantly, allows that, when struct ref can
represent a symref, http_fetch_ref() can return one.
Incidentally makes the string that http_fetch_ref() gets include "refs/"
(if appropriate), because that's how the name field of struct ref works.
As far as I can tell, the usage in walker:interpret_target() wouldn't have
worked previously, if it ever would have been used, which it wouldn't
(since the fetch process uses the hash instead of the name of the ref
there).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-26 23:53:09 +04:00
free ( ref ) ;
2006-03-11 07:18:18 +03:00
return ;
}
2015-11-10 05:22:20 +03:00
o = parse_object ( ref - > old_oid . hash ) ;
2006-03-11 07:18:18 +03:00
if ( ! o ) {
fprintf ( stderr ,
" Unable to parse object %s for remote ref %s \n " ,
2015-11-10 05:22:20 +03:00
oid_to_hex ( & ref - > old_oid ) , ls - > dentry_name ) ;
2006-03-11 07:18:18 +03:00
aborted = 1 ;
Make walker.fetch_ref() take a struct ref.
This simplifies a few things, makes a few things slightly more
complicated, but, more importantly, allows that, when struct ref can
represent a symref, http_fetch_ref() can return one.
Incidentally makes the string that http_fetch_ref() gets include "refs/"
(if appropriate), because that's how the name field of struct ref works.
As far as I can tell, the usage in walker:interpret_target() wouldn't have
worked previously, if it ever would have been used, which it wouldn't
(since the fetch process uses the hash instead of the name of the ref
there).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-26 23:53:09 +04:00
free ( ref ) ;
2006-03-11 07:18:18 +03:00
return ;
}
2015-09-25 00:07:29 +03:00
strbuf_addf ( buf , " %s \t %s \n " ,
2015-11-10 05:22:20 +03:00
oid_to_hex ( & ref - > old_oid ) , ls - > dentry_name ) ;
2006-03-11 07:18:18 +03:00
2006-07-12 07:45:31 +04:00
if ( o - > type = = OBJ_TAG ) {
2006-03-11 07:18:18 +03:00
o = deref_tag ( o , ls - > dentry_name , 0 ) ;
2015-09-25 00:07:29 +03:00
if ( o )
strbuf_addf ( buf , " %s \t %s^{} \n " ,
2015-11-10 05:22:28 +03:00
oid_to_hex ( & o - > oid ) , ls - > dentry_name ) ;
2006-03-11 07:18:18 +03:00
}
Make walker.fetch_ref() take a struct ref.
This simplifies a few things, makes a few things slightly more
complicated, but, more importantly, allows that, when struct ref can
represent a symref, http_fetch_ref() can return one.
Incidentally makes the string that http_fetch_ref() gets include "refs/"
(if appropriate), because that's how the name field of struct ref works.
As far as I can tell, the usage in walker:interpret_target() wouldn't have
worked previously, if it ever would have been used, which it wouldn't
(since the fetch process uses the hash instead of the name of the ref
there).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-04-26 23:53:09 +04:00
free ( ref ) ;
2006-03-11 07:18:18 +03:00
}
static void update_remote_info_refs ( struct remote_lock * lock )
{
2007-12-09 22:30:59 +03:00
struct buffer buffer = { STRBUF_INIT , 0 } ;
2006-03-11 07:18:18 +03:00
struct active_request_slot * slot ;
struct slot_results results ;
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
struct curl_slist * dav_headers ;
2006-03-11 07:18:18 +03:00
remote_ls ( " refs/ " , ( PROCESS_FILES | RECURSIVE ) ,
2007-12-09 22:30:59 +03:00
add_remote_info_ref , & buffer . buf ) ;
2006-03-11 07:18:18 +03:00
if ( ! aborted ) {
http-push: refactor lock-related headers creation for curl requests
DAV-related headers (more specifically, headers related to the lock token,
namely, If, Lock-Token, and Timeout) for curl requests are created and
allocated individually, eg a "if_header" variable for the "If: " header, a
"timeout_header" variable for the "Timeout: " header.
This patch provides a new function ("get_dav_token_headers") that creates
these header, saving methods from allocating memory, and from issuing a
"curl_slist_append()" call. The temporary string storage given to
curl_slist_append() is freed much earlier than the previous code with this
patch, but this change is safe, because curl_slist_append() keeps a copy
of the given string.
In part, this patch also addresses the fact that commit 753bc91 (Remove
the requirement opaquelocktoken uri scheme) did not update memory
allocations for DAV-related headers.
Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>
Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-24 05:00:22 +03:00
dav_headers = get_dav_token_headers ( lock , DAV_HEADER_IF ) ;
2006-03-11 07:18:18 +03:00
slot = get_active_slot ( ) ;
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http ( slot - > curl , lock - > url , DAV_PUT ,
& buffer , fwrite_null ) ;
2006-03-11 07:18:18 +03:00
curl_easy_setopt ( slot - > curl , CURLOPT_HTTPHEADER , dav_headers ) ;
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
if ( results . curl_result ! = CURLE_OK ) {
fprintf ( stderr ,
" PUT error: curl result=%d, HTTP code=%ld \n " ,
results . curl_result , results . http_code ) ;
}
}
}
2007-12-09 22:30:59 +03:00
strbuf_release ( & buffer . buf ) ;
2006-03-11 07:18:18 +03:00
}
static int remote_exists ( const char * path )
{
2014-06-20 01:24:33 +04:00
char * url = xstrfmt ( " %s%s " , repo - > url , path ) ;
2009-06-06 12:43:57 +04:00
int ret ;
2006-03-11 07:18:18 +03:00
2013-09-28 12:31:23 +04:00
switch ( http_get_strbuf ( url , NULL , NULL ) ) {
2009-06-06 12:43:57 +04:00
case HTTP_OK :
ret = 1 ;
break ;
case HTTP_MISSING_TARGET :
ret = 0 ;
break ;
case HTTP_ERROR :
2013-04-06 02:22:31 +04:00
error ( " unable to access '%s': %s " , url , curl_errorstr ) ;
2009-06-06 12:43:57 +04:00
default :
ret = - 1 ;
2006-03-11 07:18:18 +03:00
}
2007-12-11 00:36:11 +03:00
free ( url ) ;
return ret ;
2006-03-11 07:18:18 +03:00
}
2017-05-07 01:10:03 +03:00
static void fetch_symref ( const char * path , char * * symref , struct object_id * oid )
2006-03-20 21:31:06 +03:00
{
2014-06-20 01:24:33 +04:00
char * url = xstrfmt ( " %s%s " , repo - > url , path ) ;
2007-12-09 22:30:59 +03:00
struct strbuf buffer = STRBUF_INIT ;
use skip_prefix to avoid magic numbers
It's a common idiom to match a prefix and then skip past it
with a magic number, like:
if (starts_with(foo, "bar"))
foo += 3;
This is easy to get wrong, since you have to count the
prefix string yourself, and there's no compiler check if the
string changes. We can use skip_prefix to avoid the magic
numbers here.
Note that some of these conversions could be much shorter.
For example:
if (starts_with(arg, "--foo=")) {
bar = arg + 6;
continue;
}
could become:
if (skip_prefix(arg, "--foo=", &bar))
continue;
However, I have left it as:
if (skip_prefix(arg, "--foo=", &v)) {
bar = v;
continue;
}
to visually match nearby cases which need to actually
process the string. Like:
if (skip_prefix(arg, "--foo=", &v)) {
bar = atoi(v);
continue;
}
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-18 23:47:50 +04:00
const char * name ;
2006-03-20 21:31:06 +03:00
2013-09-28 12:31:23 +04:00
if ( http_get_strbuf ( url , & buffer , NULL ) ! = HTTP_OK )
2009-06-06 12:43:58 +04:00
die ( " Couldn't get %s for remote symref \n %s " , url ,
curl_errorstr ) ;
2006-03-20 21:31:06 +03:00
free ( url ) ;
Avoid unnecessary "if-before-free" tests.
This change removes all obvious useless if-before-free tests.
E.g., it replaces code like this:
if (some_expression)
free (some_expression);
with the now-equivalent:
free (some_expression);
It is equivalent not just because POSIX has required free(NULL)
to work for a long time, but simply because it has worked for
so long that no reasonable porting target fails the test.
Here's some evidence from nearly 1.5 years ago:
http://www.winehq.org/pipermail/wine-patches/2006-October/031544.html
FYI, the change below was prepared by running the following:
git ls-files -z | xargs -0 \
perl -0x3b -pi -e \
's/\bif\s*\(\s*(\S+?)(?:\s*!=\s*NULL)?\s*\)\s+(free\s*\(\s*\1\s*\))/$2/s'
Note however, that it doesn't handle brace-enclosed blocks like
"if (x) { free (x); }". But that's ok, since there were none like
that in git sources.
Beware: if you do use the above snippet, note that it can
produce syntactically invalid C code. That happens when the
affected "if"-statement has a matching "else".
E.g., it would transform this
if (x)
free (x);
else
foo ();
into this:
free (x);
else
foo ();
There were none of those here, either.
If you're interested in automating detection of the useless
tests, you might like the useless-if-before-free script in gnulib:
[it *does* detect brace-enclosed free statements, and has a --name=S
option to make it detect free-like functions with different names]
http://git.sv.gnu.org/gitweb/?p=gnulib.git;a=blob;f=build-aux/useless-if-before-free
Addendum:
Remove one more (in imap-send.c), spotted by Jean-Luc Herren <jlh@gmx.ch>.
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-01-31 20:26:32 +03:00
free ( * symref ) ;
2006-03-20 21:31:06 +03:00
* symref = NULL ;
2017-05-07 01:10:03 +03:00
oidclr ( oid ) ;
2006-03-20 21:31:06 +03:00
2007-12-09 22:30:59 +03:00
if ( buffer . len = = 0 )
2006-03-20 21:31:06 +03:00
return ;
http-push: trim trailing newline from remote symref
When we fetch a symbolic ref file from the remote, we get
the whole string "ref: refs/heads/master\n", recognize it by
skipping past the "ref: ", and store the rest. We should
chomp the trailing newline.
This bug was introduced in ae021d8 (use skip_prefix to avoid
magic numbers, 2014-06-18), which did not notice that the
length computation fed to xmemdupz was quietly tweaked by 1
to account for this.
We can solve it by explicitly trimming the newline, which is
more obvious. Note that we use strbuf_rtrim here, which will
actually cut off any trailing whitespace, not just a single
newline. This is a good thing, though, as it makes our
parsing more liberal (and spaces are not valid in refnames
anyway).
Signed-off-by: Jeff King <peff@peff.net>
Tested-by: Kyle J. McKay <mackyle@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-01-13 05:28:58 +03:00
/* Cut off trailing newline. */
strbuf_rtrim ( & buffer ) ;
2006-03-20 21:31:06 +03:00
/* If it's a symref, set the refname; otherwise try for a sha1 */
use skip_prefix to avoid magic numbers
It's a common idiom to match a prefix and then skip past it
with a magic number, like:
if (starts_with(foo, "bar"))
foo += 3;
This is easy to get wrong, since you have to count the
prefix string yourself, and there's no compiler check if the
string changes. We can use skip_prefix to avoid the magic
numbers here.
Note that some of these conversions could be much shorter.
For example:
if (starts_with(arg, "--foo=")) {
bar = arg + 6;
continue;
}
could become:
if (skip_prefix(arg, "--foo=", &bar))
continue;
However, I have left it as:
if (skip_prefix(arg, "--foo=", &v)) {
bar = v;
continue;
}
to visually match nearby cases which need to actually
process the string. Like:
if (skip_prefix(arg, "--foo=", &v)) {
bar = atoi(v);
continue;
}
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-06-18 23:47:50 +04:00
if ( skip_prefix ( buffer . buf , " ref: " , & name ) ) {
* symref = xmemdupz ( name , buffer . len - ( name - buffer . buf ) ) ;
2006-03-20 21:31:06 +03:00
} else {
2017-05-07 01:10:03 +03:00
get_oid_hex ( buffer . buf , oid ) ;
2006-03-20 21:31:06 +03:00
}
2007-12-09 22:30:59 +03:00
strbuf_release ( & buffer ) ;
2006-03-20 21:31:06 +03:00
}
2017-05-07 01:10:03 +03:00
static int verify_merge_base ( struct object_id * head_oid , struct ref * remote )
2006-03-20 21:31:06 +03:00
{
Convert lookup_commit* to struct object_id
Convert lookup_commit, lookup_commit_or_die,
lookup_commit_reference, and lookup_commit_reference_gently to take
struct object_id arguments.
Introduce a temporary in parse_object buffer in order to convert this
function. This is required since in order to convert parse_object and
parse_object_buffer, lookup_commit_reference_gently and
lookup_commit_or_die would need to be converted. Not introducing a
temporary would therefore require that lookup_commit_or_die take a
struct object_id *, but lookup_commit would take unsigned char *,
leaving a confusing and hard-to-use interface.
parse_object_buffer will lose this temporary in a later patch.
This commit was created with manual changes to commit.c, commit.h, and
object.c, plus the following semantic patch:
@@
expression E1, E2;
@@
- lookup_commit_reference_gently(E1.hash, E2)
+ lookup_commit_reference_gently(&E1, E2)
@@
expression E1, E2;
@@
- lookup_commit_reference_gently(E1->hash, E2)
+ lookup_commit_reference_gently(E1, E2)
@@
expression E1;
@@
- lookup_commit_reference(E1.hash)
+ lookup_commit_reference(&E1)
@@
expression E1;
@@
- lookup_commit_reference(E1->hash)
+ lookup_commit_reference(E1)
@@
expression E1;
@@
- lookup_commit(E1.hash)
+ lookup_commit(&E1)
@@
expression E1;
@@
- lookup_commit(E1->hash)
+ lookup_commit(E1)
@@
expression E1, E2;
@@
- lookup_commit_or_die(E1.hash, E2)
+ lookup_commit_or_die(&E1, E2)
@@
expression E1, E2;
@@
- lookup_commit_or_die(E1->hash, E2)
+ lookup_commit_or_die(E1, E2)
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-05-07 01:10:10 +03:00
struct commit * head = lookup_commit_or_die ( head_oid , " HEAD " ) ;
struct commit * branch = lookup_commit_or_die ( & remote - > old_oid ,
remote - > name ) ;
2006-03-20 21:31:06 +03:00
2012-08-28 02:21:37 +04:00
return in_merge_bases ( branch , head ) ;
2006-03-20 21:31:06 +03:00
}
2011-05-03 19:47:28 +04:00
static int delete_remote_branch ( const char * pattern , int force )
2006-03-20 21:31:06 +03:00
{
struct ref * refs = remote_refs ;
struct ref * remote_ref = NULL ;
2017-05-07 01:10:03 +03:00
struct object_id head_oid ;
2006-03-20 21:31:06 +03:00
char * symref = NULL ;
int match ;
int patlen = strlen ( pattern ) ;
int i ;
struct active_request_slot * slot ;
struct slot_results results ;
char * url ;
/* Find the remote branch(es) matching the specified branch name */
for ( match = 0 ; refs ; refs = refs - > next ) {
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 ] ! = ' / ' )
continue ;
match + + ;
remote_ref = refs ;
}
if ( match = = 0 )
return error ( " No remote branch matches %s " , pattern ) ;
if ( match ! = 1 )
return error ( " More than one remote branch matches %s " ,
pattern ) ;
/*
* Remote HEAD must be a symref ( not exactly foolproof ; a remote
* symlink to a symref will look like a symref )
*/
2017-05-07 01:10:03 +03:00
fetch_symref ( " HEAD " , & symref , & head_oid ) ;
2006-03-20 21:31:06 +03:00
if ( ! symref )
return error ( " Remote HEAD is not a symref " ) ;
/* Remote branch must not be the remote HEAD */
2011-08-26 01:46:52 +04:00
for ( i = 0 ; symref & & i < MAXDEPTH ; i + + ) {
2006-03-20 21:31:06 +03:00
if ( ! strcmp ( remote_ref - > name , symref ) )
return error ( " Remote branch %s is the current HEAD " ,
remote_ref - > name ) ;
2017-05-07 01:10:03 +03:00
fetch_symref ( symref , & symref , & head_oid ) ;
2006-03-20 21:31:06 +03:00
}
/* Run extra sanity checks if delete is not forced */
if ( ! force ) {
/* Remote HEAD must resolve to a known object */
if ( symref )
return error ( " Remote HEAD symrefs too deep " ) ;
2017-05-07 01:10:03 +03:00
if ( is_null_oid ( & head_oid ) )
2006-03-20 21:31:06 +03:00
return error ( " Unable to resolve remote HEAD " ) ;
2017-05-07 01:10:03 +03:00
if ( ! has_object_file ( & head_oid ) )
return error ( " Remote HEAD resolves to object %s \n which does not exist locally, perhaps you need to fetch? " , oid_to_hex ( & head_oid ) ) ;
2006-03-20 21:31:06 +03:00
/* Remote branch must resolve to a known object */
2015-11-10 05:22:20 +03:00
if ( is_null_oid ( & remote_ref - > old_oid ) )
2006-03-20 21:31:06 +03:00
return error ( " Unable to resolve remote branch %s " ,
remote_ref - > name ) ;
2015-11-10 05:22:20 +03:00
if ( ! has_object_file ( & remote_ref - > old_oid ) )
return error ( " Remote branch %s resolves to object %s \n which does not exist locally, perhaps you need to fetch? " , remote_ref - > name , oid_to_hex ( & remote_ref - > old_oid ) ) ;
2006-03-20 21:31:06 +03:00
/* Remote branch must be an ancestor of remote HEAD */
2017-05-07 01:10:03 +03:00
if ( ! verify_merge_base ( & head_oid , remote_ref ) ) {
2007-11-03 05:39:44 +03:00
return error ( " The branch '%s' is not an ancestor "
" of your current HEAD. \n "
" If you are sure you want to delete it, "
" run: \n \t 'git http-push -D %s %s' " ,
2009-03-19 02:43:53 +03:00
remote_ref - > name , repo - > url , pattern ) ;
2006-03-20 21:31:06 +03:00
}
}
/* Send delete request */
fprintf ( stderr , " Removing remote branch '%s' \n " , remote_ref - > name ) ;
2008-02-27 22:27:53 +03:00
if ( dry_run )
return 0 ;
2014-06-20 01:24:33 +04:00
url = xstrfmt ( " %s%s " , repo - > url , remote_ref - > name ) ;
2006-03-20 21:31:06 +03:00
slot = get_active_slot ( ) ;
slot - > results = & results ;
2011-05-03 19:47:29 +04:00
curl_setup_http_get ( slot - > curl , url , DAV_DELETE ) ;
2006-03-20 21:31:06 +03:00
if ( start_active_slot ( slot ) ) {
run_active_slot ( slot ) ;
free ( url ) ;
if ( results . curl_result ! = CURLE_OK )
2012-04-30 04:28:45 +04:00
return error ( " DELETE request failed (%d/%ld) " ,
2006-03-20 21:31:06 +03:00
results . curl_result , results . http_code ) ;
} else {
free ( url ) ;
return error ( " Unable to start DELETE request " ) ;
}
return 0 ;
}
2009-06-18 21:28:43 +04:00
static void run_request_queue ( void )
2009-06-06 12:43:27 +04:00
{
# ifdef USE_CURL_MULTI
is_running_queue = 1 ;
fill_active_slots ( ) ;
add_fill_function ( NULL , fill_active_slot ) ;
# endif
do {
finish_all_active_slots ( ) ;
# ifdef USE_CURL_MULTI
fill_active_slots ( ) ;
# endif
} while ( request_queue_head & & ! aborted ) ;
# ifdef USE_CURL_MULTI
is_running_queue = 0 ;
# endif
}
add an extra level of indirection to main()
There are certain startup tasks that we expect every git
process to do. In some cases this is just to improve the
quality of the program (e.g., setting up gettext()). In
others it is a requirement for using certain functions in
libgit.a (e.g., system_path() expects that you have called
git_extract_argv0_path()).
Most commands are builtins and are covered by the git.c
version of main(). However, there are still a few external
commands that use their own main(). Each of these has to
remember to include the correct startup sequence, and we are
not always consistent.
Rather than just fix the inconsistencies, let's make this
harder to get wrong by providing a common main() that can
run this standard startup.
We basically have two options to do this:
- the compat/mingw.h file already does something like this by
adding a #define that replaces the definition of main with a
wrapper that calls mingw_startup().
The upside is that the code in each program doesn't need
to be changed at all; it's rewritten on the fly by the
preprocessor.
The downside is that it may make debugging of the startup
sequence a bit more confusing, as the preprocessor is
quietly inserting new code.
- the builtin functions are all of the form cmd_foo(),
and git.c's main() calls them.
This is much more explicit, which may make things more
obvious to somebody reading the code. It's also more
flexible (because of course we have to figure out _which_
cmd_foo() to call).
The downside is that each of the builtins must define
cmd_foo(), instead of just main().
This patch chooses the latter option, preferring the more
explicit approach, even though it is more invasive. We
introduce a new file common-main.c, with the "real" main. It
expects to call cmd_main() from whatever other objects it is
linked against.
We link common-main.o against anything that links against
libgit.a, since we know that such programs will need to do
this setup. Note that common-main.o can't actually go inside
libgit.a, as the linker would not pick up its main()
function automatically (it has no callers).
The rest of the patch is just adjusting all of the various
external programs (mostly in t/helper) to use cmd_main().
I've provided a global declaration for cmd_main(), which
means that all of the programs also need to match its
signature. In particular, many functions need to switch to
"const char **" instead of "char **" for argv. This effect
ripples out to a few other variables and functions, as well.
This makes the patch even more invasive, but the end result
is much better. We should be treating argv strings as const
anyway, and now all programs conform to the same signature
(which also matches the way builtins are defined).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-01 08:58:58 +03:00
int cmd_main ( int argc , const char * * argv )
2005-11-02 22:19:24 +03:00
{
struct transfer_request * request ;
struct transfer_request * next_request ;
int nr_refspec = 0 ;
add an extra level of indirection to main()
There are certain startup tasks that we expect every git
process to do. In some cases this is just to improve the
quality of the program (e.g., setting up gettext()). In
others it is a requirement for using certain functions in
libgit.a (e.g., system_path() expects that you have called
git_extract_argv0_path()).
Most commands are builtins and are covered by the git.c
version of main(). However, there are still a few external
commands that use their own main(). Each of these has to
remember to include the correct startup sequence, and we are
not always consistent.
Rather than just fix the inconsistencies, let's make this
harder to get wrong by providing a common main() that can
run this standard startup.
We basically have two options to do this:
- the compat/mingw.h file already does something like this by
adding a #define that replaces the definition of main with a
wrapper that calls mingw_startup().
The upside is that the code in each program doesn't need
to be changed at all; it's rewritten on the fly by the
preprocessor.
The downside is that it may make debugging of the startup
sequence a bit more confusing, as the preprocessor is
quietly inserting new code.
- the builtin functions are all of the form cmd_foo(),
and git.c's main() calls them.
This is much more explicit, which may make things more
obvious to somebody reading the code. It's also more
flexible (because of course we have to figure out _which_
cmd_foo() to call).
The downside is that each of the builtins must define
cmd_foo(), instead of just main().
This patch chooses the latter option, preferring the more
explicit approach, even though it is more invasive. We
introduce a new file common-main.c, with the "real" main. It
expects to call cmd_main() from whatever other objects it is
linked against.
We link common-main.o against anything that links against
libgit.a, since we know that such programs will need to do
this setup. Note that common-main.o can't actually go inside
libgit.a, as the linker would not pick up its main()
function automatically (it has no callers).
The rest of the patch is just adjusting all of the various
external programs (mostly in t/helper) to use cmd_main().
I've provided a global declaration for cmd_main(), which
means that all of the programs also need to match its
signature. In particular, many functions need to switch to
"const char **" instead of "char **" for argv. This effect
ripples out to a few other variables and functions, as well.
This makes the patch even more invasive, but the end result
is much better. We should be treating argv strings as const
anyway, and now all programs conform to the same signature
(which also matches the way builtins are defined).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-01 08:58:58 +03:00
const char * * refspec = NULL ;
2006-03-11 07:18:12 +03:00
struct remote_lock * ref_lock = NULL ;
2006-03-11 07:18:18 +03:00
struct remote_lock * info_ref_lock = NULL ;
2006-03-08 03:13:20 +03:00
struct rev_info revs ;
2006-03-20 21:31:06 +03:00
int delete_branch = 0 ;
int force_delete = 0 ;
2006-03-11 07:18:33 +03:00
int objects_to_send ;
2005-11-02 22:19:24 +03:00
int rc = 0 ;
int i ;
2006-03-22 02:49:05 +03:00
int new_refs ;
2009-02-25 11:32:11 +03:00
struct ref * ref , * local_refs ;
2005-11-02 22:19:24 +03:00
2014-05-26 19:33:50 +04:00
repo = xcalloc ( 1 , sizeof ( * repo ) ) ;
2005-11-02 22:19:24 +03:00
argv + + ;
for ( i = 1 ; i < argc ; i + + , argv + + ) {
add an extra level of indirection to main()
There are certain startup tasks that we expect every git
process to do. In some cases this is just to improve the
quality of the program (e.g., setting up gettext()). In
others it is a requirement for using certain functions in
libgit.a (e.g., system_path() expects that you have called
git_extract_argv0_path()).
Most commands are builtins and are covered by the git.c
version of main(). However, there are still a few external
commands that use their own main(). Each of these has to
remember to include the correct startup sequence, and we are
not always consistent.
Rather than just fix the inconsistencies, let's make this
harder to get wrong by providing a common main() that can
run this standard startup.
We basically have two options to do this:
- the compat/mingw.h file already does something like this by
adding a #define that replaces the definition of main with a
wrapper that calls mingw_startup().
The upside is that the code in each program doesn't need
to be changed at all; it's rewritten on the fly by the
preprocessor.
The downside is that it may make debugging of the startup
sequence a bit more confusing, as the preprocessor is
quietly inserting new code.
- the builtin functions are all of the form cmd_foo(),
and git.c's main() calls them.
This is much more explicit, which may make things more
obvious to somebody reading the code. It's also more
flexible (because of course we have to figure out _which_
cmd_foo() to call).
The downside is that each of the builtins must define
cmd_foo(), instead of just main().
This patch chooses the latter option, preferring the more
explicit approach, even though it is more invasive. We
introduce a new file common-main.c, with the "real" main. It
expects to call cmd_main() from whatever other objects it is
linked against.
We link common-main.o against anything that links against
libgit.a, since we know that such programs will need to do
this setup. Note that common-main.o can't actually go inside
libgit.a, as the linker would not pick up its main()
function automatically (it has no callers).
The rest of the patch is just adjusting all of the various
external programs (mostly in t/helper) to use cmd_main().
I've provided a global declaration for cmd_main(), which
means that all of the programs also need to match its
signature. In particular, many functions need to switch to
"const char **" instead of "char **" for argv. This effect
ripples out to a few other variables and functions, as well.
This makes the patch even more invasive, but the end result
is much better. We should be treating argv strings as const
anyway, and now all programs conform to the same signature
(which also matches the way builtins are defined).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-07-01 08:58:58 +03:00
const char * arg = * argv ;
2005-11-02 22:19:24 +03:00
if ( * arg = = ' - ' ) {
2006-03-08 03:13:20 +03:00
if ( ! strcmp ( arg , " --all " ) ) {
2007-11-10 02:32:10 +03:00
push_all = MATCH_REFS_ALL ;
2005-11-02 22:19:24 +03:00
continue ;
}
if ( ! strcmp ( arg , " --force " ) ) {
force_all = 1 ;
continue ;
}
2007-10-16 08:35:22 +04:00
if ( ! strcmp ( arg , " --dry-run " ) ) {
dry_run = 1 ;
continue ;
}
2009-10-31 03:47:30 +03:00
if ( ! strcmp ( arg , " --helper-status " ) ) {
helper_status = 1 ;
continue ;
}
2005-11-02 22:19:24 +03:00
if ( ! strcmp ( arg , " --verbose " ) ) {
push_verbosely = 1 ;
2009-06-06 12:43:41 +04:00
http_is_verbose = 1 ;
2005-11-02 22:19:24 +03:00
continue ;
}
2006-03-20 21:31:06 +03:00
if ( ! strcmp ( arg , " -d " ) ) {
delete_branch = 1 ;
continue ;
}
if ( ! strcmp ( arg , " -D " ) ) {
delete_branch = 1 ;
force_delete = 1 ;
continue ;
}
2009-11-09 13:47:34 +03:00
if ( ! strcmp ( arg , " -h " ) )
usage ( http_push_usage ) ;
2005-11-02 22:19:24 +03:00
}
2009-03-19 02:43:53 +03:00
if ( ! repo - > url ) {
2006-03-08 03:13:20 +03:00
char * path = strstr ( arg , " // " ) ;
2010-11-25 11:21:09 +03:00
str_end_url_with_slash ( arg , & repo - > url ) ;
repo - > path_len = strlen ( repo - > url ) ;
2006-03-08 03:13:20 +03:00
if ( path ) {
2009-03-19 02:43:53 +03:00
repo - > path = strchr ( path + 2 , ' / ' ) ;
if ( repo - > path )
repo - > path_len = strlen ( repo - > path ) ;
2006-03-08 03:13:20 +03:00
}
2005-11-02 22:19:24 +03:00
continue ;
}
refspec = argv ;
nr_refspec = argc - i ;
break ;
}
2008-01-13 22:02:59 +03:00
# ifndef USE_CURL_MULTI
die ( " git-push is not available for http/https repository when not compiled with USE_CURL_MULTI " ) ;
# endif
2009-03-19 02:43:53 +03:00
if ( ! repo - > url )
2005-11-29 20:33:36 +03:00
usage ( http_push_usage ) ;
2006-03-20 21:31:06 +03:00
if ( delete_branch & & nr_refspec ! = 1 )
die ( " You must specify only one branch name when deleting a remote branch " ) ;
2009-11-09 13:47:34 +03:00
setup_git_directory ( ) ;
2006-03-08 03:13:20 +03:00
memset ( remote_dir_exists , - 1 , 256 ) ;
2005-11-07 22:39:37 +03:00
2011-12-14 04:11:56 +04:00
http_init ( NULL , repo - > url , 1 ) ;
2005-11-02 22:19:24 +03:00
2009-06-06 12:43:31 +04:00
# ifdef USE_CURL_MULTI
2009-06-06 12:43:27 +04:00
is_running_queue = 0 ;
2009-06-06 12:43:31 +04:00
# endif
2009-06-06 12:43:27 +04:00
2005-11-02 22:19:24 +03:00
/* Verify DAV compliance/lock support */
2005-11-18 22:03:18 +03:00
if ( ! locking_available ( ) ) {
2005-11-02 22:19:24 +03:00
rc = 1 ;
goto cleanup ;
}
2009-01-22 09:03:08 +03:00
sigchain_push_common ( remove_locks_on_signal ) ;
2008-05-25 22:27:44 +04:00
2006-03-11 07:18:18 +03:00
/* Check whether the remote has server info files */
2009-03-19 02:43:53 +03:00
repo - > can_update_info_refs = 0 ;
repo - > has_info_refs = remote_exists ( " info/refs " ) ;
repo - > has_info_packs = remote_exists ( " objects/info/packs " ) ;
if ( repo - > has_info_refs ) {
2006-03-11 07:18:18 +03:00
info_ref_lock = lock_remote ( " info/refs " , LOCK_TIME ) ;
if ( info_ref_lock )
2009-03-19 02:43:53 +03:00
repo - > can_update_info_refs = 1 ;
2008-01-19 18:22:48 +03:00
else {
2009-03-24 04:09:09 +03:00
error ( " cannot lock existing info/refs " ) ;
2008-01-19 18:22:48 +03:00
rc = 1 ;
goto cleanup ;
}
2006-03-11 07:18:18 +03:00
}
2009-03-19 02:43:53 +03:00
if ( repo - > has_info_packs )
2006-03-11 07:18:18 +03:00
fetch_indices ( ) ;
2006-03-08 03:13:20 +03:00
/* Get a list of all local and remote heads to validate refspecs */
2009-02-25 11:32:11 +03:00
local_refs = get_local_heads ( ) ;
2006-03-08 03:13:20 +03:00
fprintf ( stderr , " Fetching remote heads... \n " ) ;
get_dav_remote_heads ( ) ;
2009-06-06 12:43:27 +04:00
run_request_queue ( ) ;
2006-03-08 03:13:20 +03:00
2006-03-20 21:31:06 +03:00
/* Remove a remote branch if -d or -D was specified */
if ( delete_branch ) {
2009-10-31 03:47:30 +03:00
if ( delete_remote_branch ( refspec [ 0 ] , force_delete ) = = - 1 ) {
2006-03-20 21:31:06 +03:00
fprintf ( stderr , " Unable to delete remote branch %s \n " ,
refspec [ 0 ] ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " error %s cannot remove \n " , refspec [ 0 ] ) ;
}
2006-03-20 21:31:06 +03:00
goto cleanup ;
}
2006-03-08 03:13:20 +03:00
/* match them up */
2011-09-09 22:54:58 +04:00
if ( match_push_refs ( local_refs , & remote_refs ,
nr_refspec , ( const char * * ) refspec , push_all ) ) {
2008-01-19 18:22:47 +03:00
rc = - 1 ;
goto cleanup ;
}
2006-03-08 03:13:20 +03:00
if ( ! remote_refs ) {
fprintf ( stderr , " No refs in common and none specified; doing nothing. \n " ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " error null no match \n " ) ;
2008-01-19 18:22:47 +03:00
rc = 0 ;
goto cleanup ;
2006-03-08 03:13:20 +03:00
}
2006-03-22 02:49:05 +03:00
new_refs = 0 ;
2006-03-08 03:13:20 +03:00
for ( ref = remote_refs ; ref ; ref = ref - > next ) {
2015-09-25 00:07:56 +03:00
struct argv_array commit_argv = ARGV_ARRAY_INIT ;
2006-03-22 02:49:05 +03:00
2006-03-08 03:13:20 +03:00
if ( ! ref - > peer_ref )
continue ;
2008-02-27 22:27:53 +03:00
2015-11-10 05:22:20 +03:00
if ( is_null_oid ( & ref - > peer_ref - > new_oid ) ) {
2008-02-27 22:27:53 +03:00
if ( delete_remote_branch ( ref - > name , 1 ) = = - 1 ) {
error ( " Could not remove %s " , ref - > name ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " error %s cannot remove \n " , ref - > name ) ;
2008-02-27 22:27:53 +03:00
rc = - 4 ;
}
2009-10-31 03:47:30 +03:00
else if ( helper_status )
printf ( " ok %s \n " , ref - > name ) ;
2008-02-27 22:27:53 +03:00
new_refs + + ;
continue ;
}
2015-11-10 05:22:20 +03:00
if ( ! oidcmp ( & ref - > old_oid , & ref - > peer_ref - > new_oid ) ) {
2010-03-02 13:49:27 +03:00
if ( push_verbosely )
2006-03-08 03:13:20 +03:00
fprintf ( stderr , " '%s': up-to-date \n " , ref - > name ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " ok %s up to date \n " , ref - > name ) ;
2006-03-08 03:13:20 +03:00
continue ;
}
if ( ! force_all & &
2015-11-10 05:22:20 +03:00
! is_null_oid ( & ref - > old_oid ) & &
2006-03-08 03:13:20 +03:00
! ref - > force ) {
2015-11-10 05:22:20 +03:00
if ( ! has_object_file ( & ref - > old_oid ) | |
2015-11-10 05:22:25 +03:00
! ref_newer ( & ref - > peer_ref - > new_oid ,
& ref - > old_oid ) ) {
2007-11-03 05:39:44 +03:00
/*
* We do not have the remote ref , or
2006-03-08 03:13:20 +03:00
* 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 .
*/
2007-11-03 05:39:44 +03:00
error ( " remote '%s' is not an ancestor of \n "
" local '%s'. \n "
" Maybe you are not up-to-date and "
2006-03-08 03:13:20 +03:00
" need to pull first? " ,
ref - > name ,
ref - > peer_ref - > name ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " error %s non-fast forward \n " , ref - > name ) ;
2006-03-11 07:18:33 +03:00
rc = - 2 ;
2006-03-08 03:13:20 +03:00
continue ;
}
2005-11-02 22:19:24 +03:00
}
2015-11-10 05:22:20 +03:00
oidcpy ( & ref - > new_oid , & ref - > peer_ref - > new_oid ) ;
2006-03-08 03:13:20 +03:00
new_refs + + ;
fprintf ( stderr , " updating '%s' " , ref - > name ) ;
if ( strcmp ( ref - > name , ref - > peer_ref - > name ) )
fprintf ( stderr , " using '%s' " , ref - > peer_ref - > name ) ;
2015-09-25 00:08:05 +03:00
fprintf ( stderr , " \n from %s \n to %s \n " ,
2015-11-10 05:22:20 +03:00
oid_to_hex ( & ref - > old_oid ) , oid_to_hex ( & ref - > new_oid ) ) ;
2009-10-31 03:47:30 +03:00
if ( dry_run ) {
if ( helper_status )
printf ( " ok %s \n " , ref - > name ) ;
2007-10-16 08:35:22 +04:00
continue ;
2009-10-31 03:47:30 +03:00
}
2005-11-02 22:19:24 +03:00
/* Lock remote branch ref */
2006-03-08 03:13:20 +03:00
ref_lock = lock_remote ( ref - > name , LOCK_TIME ) ;
if ( ref_lock = = NULL ) {
2005-11-02 22:19:24 +03:00
fprintf ( stderr , " Unable to lock remote branch %s \n " ,
2006-03-08 03:13:20 +03:00
ref - > name ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " error %s lock error \n " , ref - > name ) ;
2005-11-02 22:19:24 +03:00
rc = 1 ;
continue ;
}
2006-03-08 03:13:20 +03:00
/* Set up revision info for this refspec */
2015-09-25 00:07:56 +03:00
argv_array_push ( & commit_argv , " " ) ; /* ignored */
argv_array_push ( & commit_argv , " --objects " ) ;
2015-11-10 05:22:20 +03:00
argv_array_push ( & commit_argv , oid_to_hex ( & ref - > new_oid ) ) ;
if ( ! push_all & & ! is_null_oid ( & ref - > old_oid ) )
2015-09-25 00:07:56 +03:00
argv_array_pushf ( & commit_argv , " ^%s " ,
2015-11-10 05:22:20 +03:00
oid_to_hex ( & ref - > old_oid ) ) ;
2006-07-29 08:21:48 +04:00
init_revisions ( & revs , setup_git_directory ( ) ) ;
2015-09-25 00:07:56 +03:00
setup_revisions ( commit_argv . argc , commit_argv . argv , & revs , NULL ) ;
2008-06-07 22:39:20 +04:00
revs . edge_hint = 0 ; /* just in case */
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
/* Generate a list of objects that need to be pushed */
2005-11-02 22:19:24 +03:00
pushing = 0 ;
2008-02-18 10:31:56 +03:00
if ( prepare_revision_walk ( & revs ) )
die ( " revision walk setup failed " ) ;
2013-08-16 13:52:06 +04:00
mark_edges_uninteresting ( & revs , NULL ) ;
2006-03-11 07:18:33 +03:00
objects_to_send = get_delta ( & revs , ref_lock ) ;
2005-11-18 22:02:58 +03:00
finish_all_active_slots ( ) ;
2005-11-02 22:19:24 +03:00
/* Push missing objects to remote, this would be a
convenient time to pack them first if appropriate . */
pushing = 1 ;
2006-03-11 07:18:33 +03:00
if ( objects_to_send )
fprintf ( stderr , " sending %d objects \n " ,
objects_to_send ) ;
2009-06-06 12:43:27 +04:00
run_request_queue ( ) ;
2005-11-02 22:19:24 +03:00
/* Update the remote branch if all went well */
2015-11-10 05:22:20 +03:00
if ( aborted | | ! update_remote ( ref - > new_oid . hash , ref_lock ) )
2006-03-08 03:13:20 +03:00
rc = 1 ;
2005-11-02 22:19:24 +03:00
2006-03-08 03:13:20 +03:00
if ( ! rc )
fprintf ( stderr , " done \n " ) ;
2009-10-31 03:47:30 +03:00
if ( helper_status )
printf ( " %s %s \n " , ! rc ? " ok " : " error " , ref - > name ) ;
2006-03-08 03:13:20 +03:00
unlock_remote ( ref_lock ) ;
2006-03-11 07:18:12 +03:00
check_locks ( ) ;
2015-09-25 00:07:56 +03:00
argv_array_clear ( & commit_argv ) ;
2005-11-02 22:19:24 +03:00
}
2006-03-11 07:18:18 +03:00
/* Update remote server info if appropriate */
2009-03-19 02:43:53 +03:00
if ( repo - > has_info_refs & & new_refs ) {
if ( info_ref_lock & & repo - > can_update_info_refs ) {
2006-03-11 07:18:18 +03:00
fprintf ( stderr , " Updating remote server info \n " ) ;
2007-10-16 08:35:22 +04:00
if ( ! dry_run )
update_remote_info_refs ( info_ref_lock ) ;
2006-03-11 07:18:18 +03:00
} else {
fprintf ( stderr , " Unable to update server info \n " ) ;
}
}
2005-11-02 22:19:24 +03:00
cleanup :
2008-01-19 18:22:47 +03:00
if ( info_ref_lock )
unlock_remote ( info_ref_lock ) ;
2009-03-19 02:43:53 +03:00
free ( repo ) ;
2005-11-02 22:19:24 +03:00
2005-11-18 22:02:58 +03:00
http_cleanup ( ) ;
2005-11-02 22:19:24 +03:00
request = request_queue_head ;
while ( request ! = NULL ) {
next_request = request - > next ;
release_request ( request ) ;
request = next_request ;
}
return rc ;
}