rugged 0.23.3 → 0.24.0b0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/ext/rugged/rugged.c +24 -0
- data/ext/rugged/rugged_config.c +65 -0
- data/ext/rugged/rugged_remote.c +22 -2
- data/ext/rugged/rugged_repo.c +10 -5
- data/ext/rugged/rugged_tree.c +4 -1
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +47 -2
- data/vendor/libgit2/include/git2/config.h +18 -0
- data/vendor/libgit2/include/git2/diff.h +25 -2
- data/vendor/libgit2/include/git2/errors.h +0 -12
- data/vendor/libgit2/include/git2/index.h +11 -0
- data/vendor/libgit2/include/git2/remote.h +12 -1
- data/vendor/libgit2/include/git2/sys/config.h +14 -0
- data/vendor/libgit2/include/git2/sys/filter.h +4 -1
- data/vendor/libgit2/include/git2/sys/odb_backend.h +4 -0
- data/vendor/libgit2/include/git2/sys/refdb_backend.h +5 -4
- data/vendor/libgit2/include/git2/sys/transport.h +27 -0
- data/vendor/libgit2/include/git2/transport.h +25 -21
- data/vendor/libgit2/include/git2/version.h +2 -2
- data/vendor/libgit2/libgit2.pc.in +3 -2
- data/vendor/libgit2/src/branch.c +1 -12
- data/vendor/libgit2/src/checkout.c +29 -20
- data/vendor/libgit2/src/clone.c +2 -2
- data/vendor/libgit2/src/common.h +13 -4
- data/vendor/libgit2/src/config.c +36 -0
- data/vendor/libgit2/src/config.h +15 -0
- data/vendor/libgit2/src/config_file.c +124 -20
- data/vendor/libgit2/src/config_file.h +10 -0
- data/vendor/libgit2/src/curl_stream.c +7 -7
- data/vendor/libgit2/src/diff.c +89 -27
- data/vendor/libgit2/src/diff_print.c +1 -1
- data/vendor/libgit2/src/errors.c +75 -40
- data/vendor/libgit2/src/filebuf.c +81 -3
- data/vendor/libgit2/src/fileops.c +176 -75
- data/vendor/libgit2/src/fileops.h +7 -10
- data/vendor/libgit2/src/filter.c +5 -2
- data/vendor/libgit2/src/global.c +25 -9
- data/vendor/libgit2/src/global.h +1 -0
- data/vendor/libgit2/src/idxmap.h +92 -0
- data/vendor/libgit2/src/ignore.c +9 -7
- data/vendor/libgit2/src/index.c +246 -46
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/iterator.c +377 -118
- data/vendor/libgit2/src/iterator.h +28 -20
- data/vendor/libgit2/src/merge.c +26 -13
- data/vendor/libgit2/src/notes.c +1 -1
- data/vendor/libgit2/src/odb.c +1 -2
- data/vendor/libgit2/src/odb_loose.c +2 -2
- data/vendor/libgit2/src/odb_mempack.c +6 -2
- data/vendor/libgit2/src/oidmap.h +2 -0
- data/vendor/libgit2/src/openssl_stream.c +9 -3
- data/vendor/libgit2/src/path.c +37 -2
- data/vendor/libgit2/src/path.h +12 -1
- data/vendor/libgit2/src/pathspec.c +12 -12
- data/vendor/libgit2/src/push.c +2 -1
- data/vendor/libgit2/src/push.h +1 -0
- data/vendor/libgit2/src/refdb.c +2 -6
- data/vendor/libgit2/src/refdb_fs.c +13 -3
- data/vendor/libgit2/src/remote.c +44 -15
- data/vendor/libgit2/src/repository.c +28 -12
- data/vendor/libgit2/src/stash.c +17 -12
- data/vendor/libgit2/src/stransport_stream.c +1 -1
- data/vendor/libgit2/src/submodule.c +234 -152
- data/vendor/libgit2/src/sysdir.c +22 -8
- data/vendor/libgit2/src/transaction.c +41 -0
- data/vendor/libgit2/src/transaction.h +14 -0
- data/vendor/libgit2/src/transports/cred.c +8 -0
- data/vendor/libgit2/src/transports/http.c +6 -0
- data/vendor/libgit2/src/transports/smart.c +95 -0
- data/vendor/libgit2/src/transports/smart.h +1 -0
- data/vendor/libgit2/src/transports/smart_pkt.c +9 -2
- data/vendor/libgit2/src/transports/ssh.c +5 -3
- data/vendor/libgit2/src/transports/winhttp.c +19 -1
- data/vendor/libgit2/src/unix/posix.h +14 -1
- data/vendor/libgit2/src/util.c +56 -13
- data/vendor/libgit2/src/util.h +13 -5
- data/vendor/libgit2/src/win32/path_w32.c +15 -8
- data/vendor/libgit2/src/win32/posix_w32.c +11 -2
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +343 -0
- data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +93 -0
- data/vendor/libgit2/src/win32/w32_stack.c +192 -0
- data/vendor/libgit2/src/win32/w32_stack.h +138 -0
- data/vendor/libgit2/src/win32/w32_util.c +29 -5
- data/vendor/libgit2/src/win32/w32_util.h +13 -3
- metadata +11 -5
data/vendor/libgit2/src/config.h
CHANGED
@@ -88,4 +88,19 @@ extern int git_config__cvar(
|
|
88
88
|
*/
|
89
89
|
int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out,
|
90
90
|
const git_cvar_map *maps, size_t map_n, int enum_val);
|
91
|
+
|
92
|
+
/**
|
93
|
+
* Unlock the backend with the highest priority
|
94
|
+
*
|
95
|
+
* Unlocking will allow other writers to updat the configuration
|
96
|
+
* file. Optionally, any changes performed since the lock will be
|
97
|
+
* applied to the configuration.
|
98
|
+
*
|
99
|
+
* @param cfg the configuration
|
100
|
+
* @param commit boolean which indicates whether to commit any changes
|
101
|
+
* done since locking
|
102
|
+
* @return 0 or an error code
|
103
|
+
*/
|
104
|
+
GIT_EXTERN(int) git_config_unlock(git_config *cfg, int commit);
|
105
|
+
|
91
106
|
#endif
|
@@ -105,6 +105,10 @@ typedef struct {
|
|
105
105
|
|
106
106
|
git_array_t(struct reader) readers;
|
107
107
|
|
108
|
+
bool locked;
|
109
|
+
git_filebuf locked_buf;
|
110
|
+
git_buf locked_content;
|
111
|
+
|
108
112
|
char *file_path;
|
109
113
|
} diskfile_backend;
|
110
114
|
|
@@ -685,6 +689,42 @@ static int config_snapshot(git_config_backend **out, git_config_backend *in)
|
|
685
689
|
return git_config_file__snapshot(out, b);
|
686
690
|
}
|
687
691
|
|
692
|
+
static int config_lock(git_config_backend *_cfg)
|
693
|
+
{
|
694
|
+
diskfile_backend *cfg = (diskfile_backend *) _cfg;
|
695
|
+
int error;
|
696
|
+
|
697
|
+
if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file_path, 0, GIT_CONFIG_FILE_MODE)) < 0)
|
698
|
+
return error;
|
699
|
+
|
700
|
+
error = git_futils_readbuffer(&cfg->locked_content, cfg->file_path);
|
701
|
+
if (error < 0 && error != GIT_ENOTFOUND) {
|
702
|
+
git_filebuf_cleanup(&cfg->locked_buf);
|
703
|
+
return error;
|
704
|
+
}
|
705
|
+
|
706
|
+
cfg->locked = true;
|
707
|
+
return 0;
|
708
|
+
|
709
|
+
}
|
710
|
+
|
711
|
+
static int config_unlock(git_config_backend *_cfg, int success)
|
712
|
+
{
|
713
|
+
diskfile_backend *cfg = (diskfile_backend *) _cfg;
|
714
|
+
int error = 0;
|
715
|
+
|
716
|
+
if (success) {
|
717
|
+
git_filebuf_write(&cfg->locked_buf, cfg->locked_content.ptr, cfg->locked_content.size);
|
718
|
+
error = git_filebuf_commit(&cfg->locked_buf);
|
719
|
+
}
|
720
|
+
|
721
|
+
git_filebuf_cleanup(&cfg->locked_buf);
|
722
|
+
git_buf_free(&cfg->locked_content);
|
723
|
+
cfg->locked = false;
|
724
|
+
|
725
|
+
return error;
|
726
|
+
}
|
727
|
+
|
688
728
|
int git_config_file__ondisk(git_config_backend **out, const char *path)
|
689
729
|
{
|
690
730
|
diskfile_backend *backend;
|
@@ -706,6 +746,8 @@ int git_config_file__ondisk(git_config_backend **out, const char *path)
|
|
706
746
|
backend->header.parent.del_multivar = config_delete_multivar;
|
707
747
|
backend->header.parent.iterator = config_iterator_new;
|
708
748
|
backend->header.parent.snapshot = config_snapshot;
|
749
|
+
backend->header.parent.lock = config_lock;
|
750
|
+
backend->header.parent.unlock = config_unlock;
|
709
751
|
backend->header.parent.free = backend_free;
|
710
752
|
|
711
753
|
*out = (git_config_backend *)backend;
|
@@ -750,6 +792,21 @@ static int config_delete_readonly(git_config_backend *cfg, const char *name)
|
|
750
792
|
return config_error_readonly();
|
751
793
|
}
|
752
794
|
|
795
|
+
static int config_lock_readonly(git_config_backend *_cfg)
|
796
|
+
{
|
797
|
+
GIT_UNUSED(_cfg);
|
798
|
+
|
799
|
+
return config_error_readonly();
|
800
|
+
}
|
801
|
+
|
802
|
+
static int config_unlock_readonly(git_config_backend *_cfg, int success)
|
803
|
+
{
|
804
|
+
GIT_UNUSED(_cfg);
|
805
|
+
GIT_UNUSED(success);
|
806
|
+
|
807
|
+
return config_error_readonly();
|
808
|
+
}
|
809
|
+
|
753
810
|
static void backend_readonly_free(git_config_backend *_backend)
|
754
811
|
{
|
755
812
|
diskfile_backend *backend = (diskfile_backend *)_backend;
|
@@ -803,6 +860,8 @@ int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in)
|
|
803
860
|
backend->header.parent.del = config_delete_readonly;
|
804
861
|
backend->header.parent.del_multivar = config_delete_multivar_readonly;
|
805
862
|
backend->header.parent.iterator = config_iterator_new;
|
863
|
+
backend->header.parent.lock = config_lock_readonly;
|
864
|
+
backend->header.parent.unlock = config_unlock_readonly;
|
806
865
|
backend->header.parent.free = backend_readonly_free;
|
807
866
|
|
808
867
|
*out = (git_config_backend *)backend;
|
@@ -1602,7 +1661,7 @@ static int config_read(git_strmap *values, diskfile_backend *cfg_file, struct re
|
|
1602
1661
|
return config_parse(reader, NULL, read_on_variable, NULL, NULL, &parse_data);
|
1603
1662
|
}
|
1604
1663
|
|
1605
|
-
static int write_section(
|
1664
|
+
static int write_section(git_buf *fbuf, const char *key)
|
1606
1665
|
{
|
1607
1666
|
int result;
|
1608
1667
|
const char *dot;
|
@@ -1626,7 +1685,7 @@ static int write_section(git_filebuf *file, const char *key)
|
|
1626
1685
|
if (git_buf_oom(&buf))
|
1627
1686
|
return -1;
|
1628
1687
|
|
1629
|
-
result =
|
1688
|
+
result = git_buf_put(fbuf, git_buf_cstr(&buf), buf.size);
|
1630
1689
|
git_buf_free(&buf);
|
1631
1690
|
|
1632
1691
|
return result;
|
@@ -1651,7 +1710,8 @@ static const char *quotes_for_value(const char *value)
|
|
1651
1710
|
}
|
1652
1711
|
|
1653
1712
|
struct write_data {
|
1654
|
-
|
1713
|
+
git_buf *buf;
|
1714
|
+
git_buf buffered_comment;
|
1655
1715
|
unsigned int in_section : 1,
|
1656
1716
|
preg_replaced : 1;
|
1657
1717
|
const char *section;
|
@@ -1660,23 +1720,28 @@ struct write_data {
|
|
1660
1720
|
const char *value;
|
1661
1721
|
};
|
1662
1722
|
|
1663
|
-
static int
|
1723
|
+
static int write_line_to(git_buf *buf, const char *line, size_t line_len)
|
1664
1724
|
{
|
1665
|
-
int result =
|
1725
|
+
int result = git_buf_put(buf, line, line_len);
|
1666
1726
|
|
1667
1727
|
if (!result && line_len && line[line_len-1] != '\n')
|
1668
|
-
result =
|
1728
|
+
result = git_buf_printf(buf, "\n");
|
1669
1729
|
|
1670
1730
|
return result;
|
1671
1731
|
}
|
1672
1732
|
|
1733
|
+
static int write_line(struct write_data *write_data, const char *line, size_t line_len)
|
1734
|
+
{
|
1735
|
+
return write_line_to(write_data->buf, line, line_len);
|
1736
|
+
}
|
1737
|
+
|
1673
1738
|
static int write_value(struct write_data *write_data)
|
1674
1739
|
{
|
1675
1740
|
const char *q;
|
1676
1741
|
int result;
|
1677
1742
|
|
1678
1743
|
q = quotes_for_value(write_data->value);
|
1679
|
-
result =
|
1744
|
+
result = git_buf_printf(write_data->buf,
|
1680
1745
|
"\t%s = %s%s%s\n", write_data->name, q, write_data->value, q);
|
1681
1746
|
|
1682
1747
|
/* If we are updating a single name/value, we're done. Setting `value`
|
@@ -1711,6 +1776,14 @@ static int write_on_section(
|
|
1711
1776
|
|
1712
1777
|
write_data->in_section = strcmp(current_section, write_data->section) == 0;
|
1713
1778
|
|
1779
|
+
/*
|
1780
|
+
* If there were comments just before this section, dump them as well.
|
1781
|
+
*/
|
1782
|
+
if (!result) {
|
1783
|
+
result = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size);
|
1784
|
+
git_buf_clear(&write_data->buffered_comment);
|
1785
|
+
}
|
1786
|
+
|
1714
1787
|
if (!result)
|
1715
1788
|
result = write_line(write_data, line, line_len);
|
1716
1789
|
|
@@ -1728,10 +1801,19 @@ static int write_on_variable(
|
|
1728
1801
|
{
|
1729
1802
|
struct write_data *write_data = (struct write_data *)data;
|
1730
1803
|
bool has_matched = false;
|
1804
|
+
int error;
|
1731
1805
|
|
1732
1806
|
GIT_UNUSED(reader);
|
1733
1807
|
GIT_UNUSED(current_section);
|
1734
1808
|
|
1809
|
+
/*
|
1810
|
+
* If there were comments just before this variable, let's dump them as well.
|
1811
|
+
*/
|
1812
|
+
if ((error = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0)
|
1813
|
+
return error;
|
1814
|
+
|
1815
|
+
git_buf_clear(&write_data->buffered_comment);
|
1816
|
+
|
1735
1817
|
/* See if we are to update this name/value pair; first examine name */
|
1736
1818
|
if (write_data->in_section &&
|
1737
1819
|
strcasecmp(write_data->name, var_name) == 0)
|
@@ -1766,7 +1848,7 @@ static int write_on_comment(struct reader **reader, const char *line, size_t lin
|
|
1766
1848
|
GIT_UNUSED(reader);
|
1767
1849
|
|
1768
1850
|
write_data = (struct write_data *)data;
|
1769
|
-
return
|
1851
|
+
return write_line_to(&write_data->buffered_comment, line, line_len);
|
1770
1852
|
}
|
1771
1853
|
|
1772
1854
|
static int write_on_eof(struct reader **reader, void *data)
|
@@ -1776,13 +1858,19 @@ static int write_on_eof(struct reader **reader, void *data)
|
|
1776
1858
|
|
1777
1859
|
GIT_UNUSED(reader);
|
1778
1860
|
|
1861
|
+
/*
|
1862
|
+
* If we've buffered comments when reaching EOF, make sure to dump them.
|
1863
|
+
*/
|
1864
|
+
if ((result = git_buf_put(write_data->buf, write_data->buffered_comment.ptr, write_data->buffered_comment.size)) < 0)
|
1865
|
+
return result;
|
1866
|
+
|
1779
1867
|
/* If we are at the EOF and have not written our value (again, for a
|
1780
1868
|
* simple name/value set, not a multivar) then we have never seen the
|
1781
1869
|
* section in question and should create a new section and write the
|
1782
1870
|
* value.
|
1783
1871
|
*/
|
1784
1872
|
if ((!write_data->preg || !write_data->preg_replaced) && write_data->value) {
|
1785
|
-
if ((result = write_section(write_data->
|
1873
|
+
if ((result = write_section(write_data->buf, write_data->section)) == 0)
|
1786
1874
|
result = write_value(write_data);
|
1787
1875
|
}
|
1788
1876
|
|
@@ -1797,18 +1885,23 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
|
|
1797
1885
|
int result;
|
1798
1886
|
char *section, *name, *ldot;
|
1799
1887
|
git_filebuf file = GIT_FILEBUF_INIT;
|
1888
|
+
git_buf buf = GIT_BUF_INIT;
|
1800
1889
|
struct reader *reader = git_array_get(cfg->readers, 0);
|
1801
1890
|
struct write_data write_data;
|
1802
1891
|
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1892
|
+
if (cfg->locked) {
|
1893
|
+
result = git_buf_puts(&reader->buffer, git_buf_cstr(&cfg->locked_content));
|
1894
|
+
} else {
|
1895
|
+
/* Lock the file */
|
1896
|
+
if ((result = git_filebuf_open(
|
1897
|
+
&file, cfg->file_path, 0, GIT_CONFIG_FILE_MODE)) < 0) {
|
1806
1898
|
git_buf_free(&reader->buffer);
|
1807
1899
|
return result;
|
1808
|
-
|
1900
|
+
}
|
1809
1901
|
|
1810
|
-
|
1811
|
-
|
1902
|
+
/* We need to read in our own config file */
|
1903
|
+
result = git_futils_readbuffer(&reader->buffer, cfg->file_path);
|
1904
|
+
}
|
1812
1905
|
|
1813
1906
|
/* Initialise the reading position */
|
1814
1907
|
if (result == GIT_ENOTFOUND) {
|
@@ -1827,7 +1920,8 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
|
|
1827
1920
|
name = ldot + 1;
|
1828
1921
|
section = git__strndup(key, ldot - key);
|
1829
1922
|
|
1830
|
-
write_data.
|
1923
|
+
write_data.buf = &buf;
|
1924
|
+
git_buf_init(&write_data.buffered_comment, 0);
|
1831
1925
|
write_data.section = section;
|
1832
1926
|
write_data.in_section = 0;
|
1833
1927
|
write_data.preg_replaced = 0;
|
@@ -1837,19 +1931,29 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
|
|
1837
1931
|
|
1838
1932
|
result = config_parse(reader, write_on_section, write_on_variable, write_on_comment, write_on_eof, &write_data);
|
1839
1933
|
git__free(section);
|
1934
|
+
git_buf_free(&write_data.buffered_comment);
|
1840
1935
|
|
1841
1936
|
if (result < 0) {
|
1842
1937
|
git_filebuf_cleanup(&file);
|
1843
1938
|
goto done;
|
1844
1939
|
}
|
1845
1940
|
|
1846
|
-
|
1847
|
-
|
1941
|
+
if (cfg->locked) {
|
1942
|
+
size_t len = buf.asize;
|
1943
|
+
/* Update our copy with the modified contents */
|
1944
|
+
git_buf_free(&cfg->locked_content);
|
1945
|
+
git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
|
1946
|
+
} else {
|
1947
|
+
git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
|
1848
1948
|
|
1849
|
-
|
1850
|
-
|
1949
|
+
/* refresh stats - if this errors, then commit will error too */
|
1950
|
+
(void)git_filebuf_stats(&reader->file_mtime, &reader->file_size, &file);
|
1951
|
+
|
1952
|
+
result = git_filebuf_commit(&file);
|
1953
|
+
}
|
1851
1954
|
|
1852
1955
|
done:
|
1956
|
+
git_buf_free(&buf);
|
1853
1957
|
git_buf_free(&reader->buffer);
|
1854
1958
|
return result;
|
1855
1959
|
}
|
@@ -55,6 +55,16 @@ GIT_INLINE(int) git_config_file_foreach_match(
|
|
55
55
|
return git_config_backend_foreach_match(cfg, regexp, fn, data);
|
56
56
|
}
|
57
57
|
|
58
|
+
GIT_INLINE(int) git_config_file_lock(git_config_backend *cfg)
|
59
|
+
{
|
60
|
+
return cfg->lock(cfg);
|
61
|
+
}
|
62
|
+
|
63
|
+
GIT_INLINE(int) git_config_file_unlock(git_config_backend *cfg, int success)
|
64
|
+
{
|
65
|
+
return cfg->unlock(cfg, success);
|
66
|
+
}
|
67
|
+
|
58
68
|
extern int git_config_file_normalize_section(char *start, char *end);
|
59
69
|
|
60
70
|
#endif
|
@@ -67,9 +67,9 @@ static int curls_certificate(git_cert **out, git_stream *stream)
|
|
67
67
|
|
68
68
|
/* No information is available, can happen with SecureTransport */
|
69
69
|
if (certinfo->num_of_certs == 0) {
|
70
|
-
s->cert_info.cert_type = GIT_CERT_NONE;
|
71
|
-
s->cert_info.data
|
72
|
-
s->cert_info.len
|
70
|
+
s->cert_info.parent.cert_type = GIT_CERT_NONE;
|
71
|
+
s->cert_info.data = NULL;
|
72
|
+
s->cert_info.len = 0;
|
73
73
|
return 0;
|
74
74
|
}
|
75
75
|
|
@@ -85,11 +85,11 @@ static int curls_certificate(git_cert **out, git_stream *stream)
|
|
85
85
|
s->cert_info_strings.strings = (char **) strings.contents;
|
86
86
|
s->cert_info_strings.count = strings.length;
|
87
87
|
|
88
|
-
s->cert_info.cert_type = GIT_CERT_STRARRAY;
|
89
|
-
s->cert_info.data
|
90
|
-
s->cert_info.len
|
88
|
+
s->cert_info.parent.cert_type = GIT_CERT_STRARRAY;
|
89
|
+
s->cert_info.data = &s->cert_info_strings;
|
90
|
+
s->cert_info.len = strings.length;
|
91
91
|
|
92
|
-
*out =
|
92
|
+
*out = &s->cert_info.parent;
|
93
93
|
|
94
94
|
return 0;
|
95
95
|
}
|
data/vendor/libgit2/src/diff.c
CHANGED
@@ -74,6 +74,32 @@ static int diff_insert_delta(
|
|
74
74
|
return error;
|
75
75
|
}
|
76
76
|
|
77
|
+
static bool diff_pathspec_match(
|
78
|
+
const char **matched_pathspec,
|
79
|
+
git_diff *diff,
|
80
|
+
const git_index_entry *entry)
|
81
|
+
{
|
82
|
+
bool disable_pathspec_match =
|
83
|
+
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH);
|
84
|
+
|
85
|
+
/* If we're disabling fnmatch, then the iterator has already applied
|
86
|
+
* the filters to the files for us and we don't have to do anything.
|
87
|
+
* However, this only applies to *files* - the iterator will include
|
88
|
+
* directories that we need to recurse into when not autoexpanding,
|
89
|
+
* so we still need to apply the pathspec match to directories.
|
90
|
+
*/
|
91
|
+
if ((S_ISLNK(entry->mode) || S_ISREG(entry->mode)) &&
|
92
|
+
disable_pathspec_match) {
|
93
|
+
*matched_pathspec = entry->path;
|
94
|
+
return true;
|
95
|
+
}
|
96
|
+
|
97
|
+
return git_pathspec__match(
|
98
|
+
&diff->pathspec, entry->path, disable_pathspec_match,
|
99
|
+
DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
|
100
|
+
matched_pathspec, NULL);
|
101
|
+
}
|
102
|
+
|
77
103
|
static int diff_delta__from_one(
|
78
104
|
git_diff *diff,
|
79
105
|
git_delta_t status,
|
@@ -110,11 +136,7 @@ static int diff_delta__from_one(
|
|
110
136
|
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNREADABLE))
|
111
137
|
return 0;
|
112
138
|
|
113
|
-
if (!
|
114
|
-
&diff->pathspec, entry->path,
|
115
|
-
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
|
116
|
-
DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
|
117
|
-
&matched_pathspec, NULL))
|
139
|
+
if (!diff_pathspec_match(&matched_pathspec, diff, entry))
|
118
140
|
return 0;
|
119
141
|
|
120
142
|
delta = diff_delta__alloc(diff, status, entry->path);
|
@@ -755,11 +777,7 @@ static int maybe_modified(
|
|
755
777
|
const char *matched_pathspec;
|
756
778
|
int error = 0;
|
757
779
|
|
758
|
-
if (!
|
759
|
-
&diff->pathspec, oitem->path,
|
760
|
-
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
|
761
|
-
DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE),
|
762
|
-
&matched_pathspec, NULL))
|
780
|
+
if (!diff_pathspec_match(&matched_pathspec, diff, oitem))
|
763
781
|
return 0;
|
764
782
|
|
765
783
|
memset(&noid, 0, sizeof(noid));
|
@@ -1053,6 +1071,12 @@ static int handle_unmatched_new_item(
|
|
1053
1071
|
&info->nitem, &untracked_state, info->new_iter)) < 0)
|
1054
1072
|
return error;
|
1055
1073
|
|
1074
|
+
/* if we found nothing that matched our pathlist filter, exclude */
|
1075
|
+
if (untracked_state == GIT_ITERATOR_STATUS_FILTERED) {
|
1076
|
+
git_vector_pop(&diff->deltas);
|
1077
|
+
git__free(last);
|
1078
|
+
}
|
1079
|
+
|
1056
1080
|
/* if we found nothing or just ignored items, update the record */
|
1057
1081
|
if (untracked_state == GIT_ITERATOR_STATUS_IGNORED ||
|
1058
1082
|
untracked_state == GIT_ITERATOR_STATUS_EMPTY) {
|
@@ -1264,11 +1288,26 @@ cleanup:
|
|
1264
1288
|
return error;
|
1265
1289
|
}
|
1266
1290
|
|
1267
|
-
#define DIFF_FROM_ITERATORS(MAKE_FIRST, MAKE_SECOND) do { \
|
1291
|
+
#define DIFF_FROM_ITERATORS(MAKE_FIRST, FLAGS_FIRST, MAKE_SECOND, FLAGS_SECOND) do { \
|
1268
1292
|
git_iterator *a = NULL, *b = NULL; \
|
1269
|
-
char *pfx = opts
|
1293
|
+
char *pfx = (opts && !(opts->flags & GIT_DIFF_DISABLE_PATHSPEC_MATCH)) ? \
|
1294
|
+
git_pathspec_prefix(&opts->pathspec) : NULL; \
|
1295
|
+
git_iterator_options a_opts = GIT_ITERATOR_OPTIONS_INIT, \
|
1296
|
+
b_opts = GIT_ITERATOR_OPTIONS_INIT; \
|
1297
|
+
a_opts.flags = FLAGS_FIRST; \
|
1298
|
+
a_opts.start = pfx; \
|
1299
|
+
a_opts.end = pfx; \
|
1300
|
+
b_opts.flags = FLAGS_SECOND; \
|
1301
|
+
b_opts.start = pfx; \
|
1302
|
+
b_opts.end = pfx; \
|
1270
1303
|
GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); \
|
1271
|
-
if (
|
1304
|
+
if (opts && (opts->flags & GIT_DIFF_DISABLE_PATHSPEC_MATCH)) { \
|
1305
|
+
a_opts.pathlist.strings = opts->pathspec.strings; \
|
1306
|
+
a_opts.pathlist.count = opts->pathspec.count; \
|
1307
|
+
b_opts.pathlist.strings = opts->pathspec.strings; \
|
1308
|
+
b_opts.pathlist.count = opts->pathspec.count; \
|
1309
|
+
} \
|
1310
|
+
if (!error && !(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
|
1272
1311
|
error = git_diff__from_iterators(diff, repo, a, b, opts); \
|
1273
1312
|
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
|
1274
1313
|
} while (0)
|
@@ -1280,8 +1319,8 @@ int git_diff_tree_to_tree(
|
|
1280
1319
|
git_tree *new_tree,
|
1281
1320
|
const git_diff_options *opts)
|
1282
1321
|
{
|
1283
|
-
int error = 0;
|
1284
1322
|
git_iterator_flag_t iflag = GIT_ITERATOR_DONT_IGNORE_CASE;
|
1323
|
+
int error = 0;
|
1285
1324
|
|
1286
1325
|
assert(diff && repo);
|
1287
1326
|
|
@@ -1293,8 +1332,8 @@ int git_diff_tree_to_tree(
|
|
1293
1332
|
iflag = GIT_ITERATOR_IGNORE_CASE;
|
1294
1333
|
|
1295
1334
|
DIFF_FROM_ITERATORS(
|
1296
|
-
git_iterator_for_tree(&a, old_tree,
|
1297
|
-
git_iterator_for_tree(&b, new_tree,
|
1335
|
+
git_iterator_for_tree(&a, old_tree, &a_opts), iflag,
|
1336
|
+
git_iterator_for_tree(&b, new_tree, &b_opts), iflag
|
1298
1337
|
);
|
1299
1338
|
|
1300
1339
|
return error;
|
@@ -1318,10 +1357,10 @@ int git_diff_tree_to_index(
|
|
1318
1357
|
git_index *index,
|
1319
1358
|
const git_diff_options *opts)
|
1320
1359
|
{
|
1321
|
-
int error = 0;
|
1322
|
-
bool index_ignore_case = false;
|
1323
1360
|
git_iterator_flag_t iflag = GIT_ITERATOR_DONT_IGNORE_CASE |
|
1324
1361
|
GIT_ITERATOR_INCLUDE_CONFLICTS;
|
1362
|
+
bool index_ignore_case = false;
|
1363
|
+
int error = 0;
|
1325
1364
|
|
1326
1365
|
assert(diff && repo);
|
1327
1366
|
|
@@ -1331,8 +1370,8 @@ int git_diff_tree_to_index(
|
|
1331
1370
|
index_ignore_case = index->ignore_case;
|
1332
1371
|
|
1333
1372
|
DIFF_FROM_ITERATORS(
|
1334
|
-
git_iterator_for_tree(&a, old_tree,
|
1335
|
-
git_iterator_for_index(&b, index,
|
1373
|
+
git_iterator_for_tree(&a, old_tree, &a_opts), iflag,
|
1374
|
+
git_iterator_for_index(&b, index, &b_opts), iflag
|
1336
1375
|
);
|
1337
1376
|
|
1338
1377
|
/* if index is in case-insensitive order, re-sort deltas to match */
|
@@ -1356,10 +1395,11 @@ int git_diff_index_to_workdir(
|
|
1356
1395
|
return error;
|
1357
1396
|
|
1358
1397
|
DIFF_FROM_ITERATORS(
|
1359
|
-
git_iterator_for_index(
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1398
|
+
git_iterator_for_index(&a, index, &a_opts),
|
1399
|
+
GIT_ITERATOR_INCLUDE_CONFLICTS,
|
1400
|
+
|
1401
|
+
git_iterator_for_workdir(&b, repo, index, NULL, &b_opts),
|
1402
|
+
GIT_ITERATOR_DONT_AUTOEXPAND
|
1363
1403
|
);
|
1364
1404
|
|
1365
1405
|
if (!error && DIFF_FLAG_IS_SET(*diff, GIT_DIFF_UPDATE_INDEX) && (*diff)->index_updated)
|
@@ -1383,9 +1423,8 @@ int git_diff_tree_to_workdir(
|
|
1383
1423
|
return error;
|
1384
1424
|
|
1385
1425
|
DIFF_FROM_ITERATORS(
|
1386
|
-
git_iterator_for_tree(&a, old_tree,
|
1387
|
-
git_iterator_for_workdir(
|
1388
|
-
&b, repo, index, old_tree, GIT_ITERATOR_DONT_AUTOEXPAND, pfx, pfx)
|
1426
|
+
git_iterator_for_tree(&a, old_tree, &a_opts), 0,
|
1427
|
+
git_iterator_for_workdir(&b, repo, index, old_tree, &b_opts), GIT_ITERATOR_DONT_AUTOEXPAND
|
1389
1428
|
);
|
1390
1429
|
|
1391
1430
|
return error;
|
@@ -1421,6 +1460,29 @@ int git_diff_tree_to_workdir_with_index(
|
|
1421
1460
|
return error;
|
1422
1461
|
}
|
1423
1462
|
|
1463
|
+
int git_diff_index_to_index(
|
1464
|
+
git_diff **diff,
|
1465
|
+
git_repository *repo,
|
1466
|
+
git_index *old_index,
|
1467
|
+
git_index *new_index,
|
1468
|
+
const git_diff_options *opts)
|
1469
|
+
{
|
1470
|
+
int error = 0;
|
1471
|
+
|
1472
|
+
assert(diff && old_index && new_index);
|
1473
|
+
|
1474
|
+
DIFF_FROM_ITERATORS(
|
1475
|
+
git_iterator_for_index(&a, old_index, &a_opts), GIT_ITERATOR_DONT_IGNORE_CASE,
|
1476
|
+
git_iterator_for_index(&b, new_index, &b_opts), GIT_ITERATOR_DONT_IGNORE_CASE
|
1477
|
+
);
|
1478
|
+
|
1479
|
+
/* if index is in case-insensitive order, re-sort deltas to match */
|
1480
|
+
if (!error && (old_index->ignore_case || new_index->ignore_case))
|
1481
|
+
diff_set_ignore_case(*diff, true);
|
1482
|
+
|
1483
|
+
return error;
|
1484
|
+
}
|
1485
|
+
|
1424
1486
|
size_t git_diff_num_deltas(const git_diff *diff)
|
1425
1487
|
{
|
1426
1488
|
assert(diff);
|