@@ -101,65 +101,112 @@ void checkout_progress(
101101
102102/* … * /
103103progress_data d = {0};
104- git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
105- git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
104+ git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
106105
107- checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE ;
108- checkout_opts.progress_cb = checkout_progress;
109- checkout_opts.progress_payload = &d;
106+ clone_opts. checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE ;
107+ clone_opts. checkout_opts.progress_cb = checkout_progress;
108+ clone_opts. checkout_opts.progress_payload = &d;
110109clone_opts.checkout_opts = checkout_opts;
111- clone_opts.remote_callbacks. transfer_progress = & fetch_progress;
112- clone_opts.remote_callbacks .payload = &d;
110+ clone_opts.fetch_opts.callbacks. transfer_progress = fetch_progress;
111+ clone_opts.fetch_opts.callbacks .payload = &d;
113112
114113git_repository * repo = NULL;
115- int error = git_clone(&repo, url, path, &opts );
114+ int error = git_clone(&repo, url, path, &clone_opts );
116115```
117116
118117([`git_clone`](http://libgit2.github.com/libgit2/#HEAD/group/clone/git_clone),
119118[`git_clone_options`](http://libgit2.github.com/libgit2/#HEAD/type/git_clone_options))
120119
121120
122- <h3 id="repositories_clone_repo">Clone (Repo )</h3>
121+ <h3 id="repositories_clone_repo">Clone (Custom repo and remote )</h3>
123122
124123```c
125- git_repository *repo = NULL;
126- error = git_repository_init(&repo, "/tmp/…", false);
127- /* Customize the repo */
124+ int create_repsitory(git_repository **out, const char *path, int bare, void *payload)
125+ {
126+ int error;
127+
128+ /*
129+ * We create the repository ourselves, libgit2 gives us the parameters it would
130+ * have used to create the repository. In this case we ignore the path passed
131+ * to git_clone() and put it under /tmp/
132+ */
133+ if ((error = git_repository_init(out, "/tmp/...", bare)) < 0)
134+ return error;
135+
136+ /* Further customisation of the repository goes here */
137+
138+ return 0;
139+ }
140+
141+ int create_remote(git_remote **out, git_repository *repo, const char *name, const char *url, void *payload)
142+ {
143+ int error;
144+
145+ /*
146+ * Like above, we create the repository based on what libgit2 would have used
147+ * (which is what was passed to git_clone. We could use a different refspec
148+ * or name.
149+ */
150+ if ((error = git_remote_create(out, repo, name, url)) < 0)
151+ return error;
128152
129- git_remote *origin = NULL;
130- error = git_remote_create(&origin, repo, "origin", "http://…");
131- /* Customize the remote, set callbacks, etc. */
153+ /* Further customisation of the remote goes here */
132154
133- git_checkout_options co_opts = GIT_CHECKOUT_OPTIONS_INIT;
134- error = git_clone_into(repo, origin, &co_opts, "master", NULL);
155+ return 0;
156+ }
157+
158+ git_repository *repo;
159+ git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
160+ clone_opts.repository_cb = create_repository;
161+ clone_opts.remote_cb = create_remote;
162+
163+ error = git_clone(&repo, url, path, &clone_opts);
135164```
136165
137166([ ` git_clone_into ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/clone/git_clone_into ) )
138167
139168<h3 id =" repositories_clone_mirror " >Clone (Mirror)</h3 >
140169
141170``` c
142- git_repository *repo = NULL ;
143- error = git_repository_init(&repo, " /tmp/…" , true );
171+ int create_remote_mirror (git_remote ** out, git_repository * repo, const char * name, const char * url, void * payload)
172+ {
173+ int error;
174+ git_remote * remote;
175+ git_config * cfg;
176+ char * mirror_config;
144177
145- /* Create an 'origin' remote with the mirror fetch refspec */
146- git_remote *origin = NULL ;
147- error = git_remote_create_with_fetchspec(
148- &origin, repo, " origin" , " http://…" , " +refs/*:refs/*" );
178+ /* Create the repository with a mirror refspec */
179+ if ((error = git_remote_create_with_fetchspec(&remote, repo, name, url, "+refs/*:refs/*")) < 0)
180+ return error;
149181
150- /* Set remote.origin.mirror = true for compatibility with git-core */
151- git_config *cfg = NULL ;
152- error = git_repository_config(&cfg, repo);
153- error = git_config_set_bool(cfg, " remote.origin.mirror" , true );
182+ /* Set the mirror setting to true on this remote */
183+ if ((error = git_repository_config(&cfg, repo)) < 0)
184+ return error;
185+
186+ if (asprintf(&mirror_config, "remote.%s.mirror", name) == -1) {
187+ giterr_set(GITERR_OS, "asprintf failed");
188+ git_config_free(cfg);
189+ return -1;
190+ }
191+
192+ error = git_repository_set_bool(cfg, mirror_config, true);
154193
155- error = git_clone_into(repo, origin, NULL , NULL );
194+ free(mirror_config);
195+ git_config_free(cfg);
196+
197+ return error;
198+ }
199+
200+ git_repository * repo = NULL;
201+ git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
202+
203+ error = git_clone(&repo, url, path, &clone_opts);
156204```
157205
158- ([ ` git_repository_init ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/repository/git_repository_init ) ,
159- [ ` git_remote_create_with_fetchspec ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_create_with_fetchspec ) ,
206+ ([`git_remote_create_with_fetchspec`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_create_with_fetchspec),
160207[`git_repository_config`](http://libgit2.github.com/libgit2/#HEAD/group/repository/git_repository_config),
161208[`git_config_set_bool`](http://libgit2.github.com/libgit2/#HEAD/group/config/git_config_set_bool),
162- [ ` git_clone_into ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/clone/git_clone_into ) )
209+ [`git_clone `](http://libgit2.github.com/libgit2/#HEAD/group/clone/git_clone ))
163210
164211<h3 id="repositories_open_simple">Open (Simple)</h3>
165212
@@ -456,16 +503,16 @@ error = git_revparse_single(&obj, repo, "HEAD:README.md");
456503error = git_treebuilder_insert(NULL , bld,
457504 " README.md" , /* filename */
458505 git_object_id (obj), /* OID * /
459- 0100644); /* mode * /
506+ GIT_FILEMODE_BLOB); /* mode * /
460507git_object_free(obj);
461508error = git_revparse_single(&obj, repo, "v0.1.0: foo /bar/baz.c");
462509error = git_treebuilder_insert(NULL, bld,
463510 "d.c",
464511 git_object_id(obj),
465- 0100644 );
512+ GIT_FILEMODE_BLOB );
466513git_object_free(obj);
467514
468- git_oid oid = {{0 }};
515+ git_oid oid = {{ 0 }};
469516error = git_treebuilder_write(&oid, repo, bld);
470517git_treebuilder_free(bld);
471518```
@@ -711,7 +758,7 @@ int error = git_reference_create(&ref, repo,
711758 " refs/heads/direct" , /* name */
712759 &oid, /* target */
713760 true , /* force? */
714- NULL , NULL ); /* use defaults for reflog */
761+ NULL ); /* the message for the reflog */
715762```
716763
717764([ ` git_reference_create ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/reference/git_reference_create ) )
@@ -724,7 +771,7 @@ int error = git_reference_symbolic_create(&ref, repo,
724771 " refs/heads/symbolic" , /* name */
725772 " refs/heads/master" , /* target */
726773 true , /* force? */
727- NULL , NULL ); /* use defaults for reflog */
774+ NULL ); /* the message for the reflog */
728775```
729776
730777([ ` git_reference_symbolic_create ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/reference/git_reference_symbolic_create ) )
@@ -1270,7 +1317,8 @@ int error = git_config_open_default(&cfg);
12701317error = git_repository_config(&cfg, repo);
12711318```
12721319
1273- Once you have a config instance, you can specify which of its levels to operate at:
1320+ Once you have a config instance, you can specify which of its levels
1321+ to operate at (if you want something other than repository's):
12741322
12751323``` c
12761324git_config *sys_cfg = NULL ;
@@ -1290,6 +1338,8 @@ Raw entries are available:
12901338``` c
12911339const git_config_entry *entry = NULL ;
12921340int error = git_config_get_entry(&entry, cfg, " diff.renames" );
1341+ /* work with it */
1342+ git_config_entry_free (entry);
12931343```
12941344
12951345Or you can let libgit2 do the parsing:
@@ -1298,11 +1348,11 @@ Or you can let libgit2 do the parsing:
12981348int32_t i32val;
12991349int64_t i64val;
13001350int boolval;
1301- const char * strval;
1351+ git_buf strval = GIT_BUF_INIT ;
13021352error = git_config_get_int32(&i32val, cfg, "foo.bar");
13031353error = git_config_get_int64(&i64val, cfg, "foo.bar");
13041354error = git_config_get_bool(&boolval, cfg, "foo.bar");
1305- error = git_config_get_string (&strval, cfg, " foo.bar" );
1355+ error = git_config_get_string_buf (&strval, cfg, "foo.bar");
13061356```
13071357
13081358Setting values is fairly straightforward.
@@ -1468,7 +1518,7 @@ So if you want your checkout to check files out, choose an appropriate strategy.
14681518* `NONE` is the equivalent of a dry run; no files will be checked out.
14691519* `SAFE` is similar to `git checkout`; unmodified files are updated, and modified files are left alone.
14701520 If a file was present in the old HEAD but is missing, it's considered deleted, and won't be created.
1471- * `SAFE_CREATE ` is similar to `git checkout-index`, or what happens after a clone.
1521+ * `RECREATE_MISSING ` is similar to `git checkout-index`, or what happens after a clone.
14721522 Unmodified files are updated, and missing files are created, but files with modifications are left alone.
14731523* `FORCE` is similar to `git checkout --force`; all modifications are overwritten, and all missing files are created.
14741524
@@ -1582,14 +1632,14 @@ int error = git_remote_list(&remotes, repo);
15821632 [ ` git_remote_list ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_list )
15831633)
15841634
1585- <h3 id =" remotes_load " >Loading </h3 >
1635+ <h3 id =" remotes_load " >Looking up </h3 >
15861636
15871637``` c
15881638git_remote *remote = NULL ;
1589- int error = git_remote_load (&remote, repo, " origin" );
1639+ int error = git_remote_lookup (&remote, repo, " origin" );
15901640```
15911641(
1592- [ ` git_remote_load ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_load )
1642+ [ ` git_remote_load ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_lookup )
15931643)
15941644
15951645<h3 id =" remotes_create " >Creating</h3 >
@@ -1613,33 +1663,29 @@ error = git_remote_create(&newremote2, repo, "upstream2",
16131663 [ ` git_remote_create_with_fetchspec ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_create_with_fetchspec )
16141664)
16151665
1616- <h3 id =" remotes_in_memory " >Creating (in-memory)</h3 >
1666+ <h3 id =" remotes_in_memory " >Creating (anonymous)</h3 >
1667+
1668+ This method creates a remote that cannot be saved. This is the kind of
1669+ remote to use when you have a URL instead of a remote's name.
16171670
1618- This method creates a remote that cannot be saved.
1619- This is useful for one-time fetches.
16201671
16211672``` c
16221673git_remote *remote;
1623- int error = git_remote_create_inmemory(&remote, repo,)
1624- " +refs/heads/*:refs/custom/namespace/*" , /* fetchspec */
1674+ int error = git_remote_create_anonymous(&remote, repo,
16251675 " https://github.com/libgit2/libgit2" ); /* URL */
16261676```
16271677(
1628- [ ` git_remote_create_inmemory ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_create_inmemory )
1678+ [ ` git_remote_create_anonymous ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_create_anonymous )
16291679)
16301680
16311681<h3 id =" remotes_rename " >Renaming</h3 >
16321682
16331683``` c
1634- typedef struct { /* … * / } rename_data;
1635- int problem_cb(const char * problem, void * payload)
1636- {
1637- rename_data * d = (rename_data* )payload;
1638- /* Called when there's a problem renaming the remote. * /
1639- }
1684+ git_strarray problems;
16401685
1641- rename_data d = {0};
1642- int error = git_remote_rename(remote, "old_origin", problem_cb, &d);
1686+ int error = git_remote_rename(&problems, repo, " origin" , " old_origin" );
1687+ /* warn the user about the refspecs which couldn't be adjusted */
1688+ git_strarray_free (&problems);
16431689```
16441690(
16451691 [`git_remote_rename`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_rename)
@@ -1677,13 +1723,10 @@ error = git_remote_get_push_refspecs(&fetch_refspecs, remote);
16771723size_t count = git_remote_refspec_count(remote);
16781724const git_refspec * rs = git_remote_get_refspec(remote, 0);
16791725
1680- /* You can add one spec at a time * /
1681- error = git_remote_add_fetch(remote , "…");
1682- error = git_remote_add_push(remote , "…");
1726+ /* You can add refspecs to the configuration * /
1727+ error = git_remote_add_fetch(repo, "origin" , "…");
1728+ error = git_remote_add_push(repo, "origin" , "…");
16831729
1684- /* … or swap out the entire set * /
1685- error = git_remote_set_fetch_refspecs(remote, fetch_refspecs);
1686- error = git_remote_set_push_refspecs(remote, push_refspecs);
16871730```
16881731(
16891732 [`git_remote_get_fetch_refspecs`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_get_fetch_refspecs),
@@ -1692,41 +1735,22 @@ error = git_remote_set_push_refspecs(remote, push_refspecs);
16921735 [`git_remote_get_refspec`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_get_refspec),
16931736 [`git_remote_add_fetch`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_add_fetch),
16941737 [`git_remote_add_push`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_add_push),
1695- [`git_remote_set_fetch_refspecs`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_set_fetch_refspecs),
1696- [`git_remote_set_push_refspecs`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_set_push_refspecs),
16971738)
16981739
16991740<h3 id="remotes_fetching">Fetching</h3>
17001741
17011742```c
1702- /* Open a connection for reading. */
1703- int error = git_remote_connect(remote, GIT_DIRECTION_FETCH);
1704- int connected = git_remote_connected(remote);
1705-
1706- /* List the heads on the remote */
1707- const git_remote_head **remote_heads = NULL;
1708- size_t count = 0;
1709- error = git_remote_ls(&remote_heads, &count, remote);
1710- for (size_t i=0; i<count; ++i) {
1711- git_remote_head *head = remote_heads[i];
1712- /* … */
1713- }
1714-
1715- /* Negotiate and download objects */
1716- error = git_remote_download(remote);
1717-
1718- /* Update remote refs */
1719- error = git_remote_update_tips(remote, NULL, NULL);
1743+ int error;
1744+ git_remote *remote;
17201745
1721- /* All of the above in one step */
1722- error = git_remote_fetch(remote, NULL, NULL);
1746+ /* lookup the remote */
1747+ error = git_remote_lookup(&remote, repo, "origin");
1748+ error = git_remote_fetch(remote,
1749+ NULL, /* refspecs, NULL to use the configured ones */
1750+ NULL, /* options, empty for defaults */
1751+ NULL); /* reflog mesage, usually "fetch" or "pull", you can leave it NULL for "fetch" */
17231752```
17241753(
1725- [ ` git_remote_connect ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_connect ) ,
1726- [ ` git_remote_connected ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_connected ) ,
1727- [ ` git_remote_ls ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_ls ) ,
1728- [ ` git_remote_download ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_download ) ,
1729- [ ` git_remote_update_tips ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_update_tips ) ,
17301754 [ ` git_remote_fetch ` ] ( http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_fetch )
17311755)
17321756
@@ -1757,10 +1781,11 @@ int credential_cb(git_cred **out,
17571781
17581782remote_data d = {0};
17591783git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
1760- callbacks.progress = progress_cb;
1761- callbacks.credentials = credential_cb;
1762- callbacks.payload = &d;
1763- int error = git_remote_set_callbacks(remote, &callbacks);
1784+ git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
1785+ fetch_opts.callbacks.progress = progress_cb;
1786+ fetch_opts.callbacks.credentials = credential_cb;
1787+ fetch_opts.callbacks.payload = &d;
1788+ int error = git_remote_fetch(remote, NULL, &fetch_opts, NULL);
17641789```
17651790
17661791For an example of the credentials callback in action, check out [the network example](https://github.com/libgit2/libgit2/blob/development/examples/network/common.c),
@@ -1769,5 +1794,4 @@ or the built-in [credential helpers](https://github.com/libgit2/libgit2/blob/dev
17691794(
17701795 [`git_remote_stop`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_stop),
17711796 [`git_remote_callbacks`](http://libgit2.github.com/libgit2/#HEAD/type/git_remote_callbacks),
1772- [`git_remote_set_callbacks`](http://libgit2.github.com/libgit2/#HEAD/group/remote/git_remote_set_callbacks)
17731797)
0 commit comments