-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapply.cpp
executable file
·115 lines (111 loc) · 3.11 KB
/
apply.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
* Apply patches, and the user interface to do so.
*/
#include <stdafx.h>
SCCRTN LGitApplyPatch(LGitContext *ctx,
HWND hwnd,
git_diff *diff,
git_apply_location_t loc,
BOOL check_only)
{
LGitLog("**LGitApplyPatchDialog** Context=%p\n", ctx);
LGitLog(" location %x\n", loc);
LGitLog(" check only? %d\n", check_only);
SCCRTN ret = SCC_OK;
git_apply_options opts;
git_apply_options_init(&opts, GIT_APPLY_OPTIONS_VERSION);
if (check_only) {
opts.flags = GIT_APPLY_CHECK;
}
if (git_apply(ctx->repo, diff, loc, &opts) != 0) {
LGitLibraryError(hwnd, "git_apply");
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
fin:
return ret;
}
SCCRTN LGitFileToDiff(LGitContext *ctx, HWND hwnd, const wchar_t *file, git_diff **out)
{
SCCRTN ret = SCC_OK;
size_t buf_sz;
HANDLE fh = INVALID_HANDLE_VALUE, mh = INVALID_HANDLE_VALUE;
char *buf;
/* we're boned if we need to allocate more than (uint32)-1 on x86 */
fh = CreateFileW(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fh == INVALID_HANDLE_VALUE) {
/* not an lg2 error */
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
buf_sz = GetFileSize(fh, NULL);
if (buf_sz == 0xFFFFFFFF) {
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
/* just get a memory mapping of the file, no need for a read */
mh = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
if (mh == INVALID_HANDLE_VALUE) {
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
buf = (char*)MapViewOfFile(mh, FILE_MAP_READ, 0, 0, 0);
if (buf == NULL) {
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
if (git_diff_from_buffer(out, buf, buf_sz) != 0) {
LGitLibraryError(hwnd, "git_diff_from_buffer");
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
fin:
if (mh != INVALID_HANDLE_VALUE) {
CloseHandle(fh);
}
if (fh != INVALID_HANDLE_VALUE) {
CloseHandle(fh);
}
return ret;
}
SCCRTN LGitApplyPatchDialog(LGitContext *ctx, HWND hwnd)
{
LGitLog("**LGitApplyPatchDialog** Context=%p\n", ctx);
OPENFILENAMEW ofn;
wchar_t fileName[MAX_PATH];
ZeroMemory(fileName, MAX_PATH);
ZeroMemory(&ofn, sizeof(OPENFILENAMEW));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrTitle = L"Apply Patch";
ofn.lpstrDefExt = L"diff";
ofn.lpstrFilter = L"Diff\0*.diff;*.patch\0";
ofn.lpstrFile = fileName;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
/* XXX: Add some stuff to the dialog for i.e. A&M, apply to, etc. */
if (GetOpenFileNameW(&ofn)) {
/* XXX: turn into loop, break into sep func */
git_diff *diff = NULL;
SCCRTN ret = SCC_OK;
if (LGitFileToDiff(ctx, hwnd, fileName, &diff) != SCC_OK) {
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
/* For now, we just apply to the working tree */
if (LGitApplyPatch(ctx, hwnd, diff, GIT_APPLY_LOCATION_WORKDIR, FALSE) != SCC_OK) {
ret = SCC_E_UNKNOWNERROR;
goto fin;
}
fin:
if (diff != NULL) {
git_diff_free(diff);
}
return ret;
} else {
DWORD err = CommDlgExtendedError();
if (err) {
LGitLog("!! OFN returned error %x\n", err);
}
return err ? SCC_E_UNKNOWNERROR : SCC_I_OPERATIONCANCELED;
}
}