-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtag.cpp
executable file
·256 lines (248 loc) · 7.1 KB
/
tag.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
/*
* Tags, but only adding. Managing is in tag.cpp...
*/
#include <stdafx.h>
typedef struct _LGitAddTagDialogParams {
LGitContext *ctx;
char new_name[128];
char based_on[128];
char message[0x1000]; /* should be cleaned up */
BOOL force;
} LGitAddTagDialogParams;
static void InitTagAddView(HWND hwnd, LGitAddTagDialogParams* params)
{
SetDlgItemText(hwnd, IDC_TAG_ADD_NAME, params->new_name);
/* yeah, we should load it from the struct... */
HWND ref_cb = GetDlgItem(hwnd, IDC_TAG_ADD_BASED_ON);
LGitPopulateReferenceComboBox(hwnd, ref_cb, params->ctx);
SetDlgItemText(hwnd, IDC_TAG_ADD_BASED_ON, "HEAD");
SetDlgItemText(hwnd, IDC_TAG_ADD_MESSAGE, params->message);
CheckDlgButton(hwnd, IDC_TAG_ADD_FORCE, params->force ? BST_CHECKED : BST_UNCHECKED);
}
static BOOL SetTagAddParams(HWND hwnd, LGitAddTagDialogParams* params)
{
GetDlgItemText(hwnd, IDC_TAG_ADD_NAME, params->new_name, 128);
GetDlgItemText(hwnd, IDC_TAG_ADD_BASED_ON, params->based_on, 128);
GetDlgItemText(hwnd, IDC_TAG_ADD_MESSAGE, params->message, 0x1000);
int valid = 0;
/* if there's an error, then if it's valid */
if (git_tag_name_is_valid(&valid, params->new_name) != 0) {
LGitLibraryError(hwnd, "git_tag_name_is_valid");
return FALSE;
}
if (!valid) {
MessageBox(hwnd,
"The tag name is invalid.",
"Invalid Tag Name",
MB_ICONWARNING);
return FALSE;
}
/* check if the reference exists */
git_object *obj = NULL;
switch (git_revparse_single(&obj, params->ctx->repo, params->based_on)) {
case GIT_ENOTFOUND:
MessageBox(hwnd,
"The reference name to base off of doesn't exist.",
"Invalid Reference Name",
MB_ICONWARNING);
return FALSE;
case GIT_EINVALIDSPEC:
MessageBox(hwnd,
"The reference name to base off of is invalid.",
"Invalid Reference Name",
MB_ICONWARNING);
return FALSE;
case GIT_EAMBIGUOUS:
MessageBox(hwnd,
"The revision given isn't specific enough.",
"Invalid Revision",
MB_ICONWARNING);
return FALSE;
case 0:
git_object_free(obj);
break;
default:
LGitLibraryError(hwnd, "git_revparse_single");
return FALSE;
}
params->force = IsDlgButtonChecked(hwnd, IDC_TAG_ADD_FORCE) == BST_CHECKED;
return TRUE;
}
static BOOL CALLBACK AddTagDialogProc(HWND hwnd,
unsigned int iMsg,
WPARAM wParam,
LPARAM lParam)
{
LGitAddTagDialogParams *param;
param = (LGitAddTagDialogParams*)GetWindowLong(hwnd, GWL_USERDATA);
switch (iMsg) {
case WM_INITDIALOG:
param = (LGitAddTagDialogParams*)lParam;
SetWindowLong(hwnd, GWL_USERDATA, (long)param); /* XXX: 64-bit... */
InitTagAddView(hwnd, param);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (SetTagAddParams(hwnd, param)) {
EndDialog(hwnd, 2);
}
return TRUE;
case IDCANCEL:
EndDialog(hwnd, 1);
return TRUE;
}
return FALSE;
case WM_MEASUREITEM:
if (wParam == IDC_TAG_ADD_BASED_ON) {
return LGitMeasureIconComboBoxItem(hwnd, wParam, (MEASUREITEMSTRUCT *)lParam);
}
return FALSE;
case WM_DRAWITEM:
if (wParam == IDC_TAG_ADD_BASED_ON) {
return LGitDrawIconComboBox(param->ctx, param->ctx->refTypeIl, hwnd, wParam, (DRAWITEMSTRUCT *)lParam);
}
return FALSE;
default:
return FALSE;
}
}
static SCCRTN CreateAnnotatedTag(LGitContext *ctx,
HWND hwnd,
const char *name,
git_commit *based_on,
const char *message,
BOOL force)
{
SCCRTN ret = SCC_OK;
git_oid tag_oid;
git_signature *signature = NULL;
git_buf prettified_message = {0, 0};
const char *message_to_use = NULL;
/* XXX: some of this logic is common to commit, share */
if (git_message_prettify(&prettified_message, message, 1, '#') != 0) {
LGitLog(" ! Failed to prettify commit, using original text\n");
message_to_use = message;
} else {
message_to_use = prettified_message.ptr;
}
if (LGitGetDefaultSignature(hwnd, ctx, &signature) != SCC_OK) {
goto fin;
}
switch (git_tag_create(&tag_oid, ctx->repo, name, (git_object*)based_on, signature, message_to_use, force)) {
case 0:
break;
case GIT_EINVALIDSPEC:
ret = SCC_E_NONSPECIFICERROR;
MessageBox(hwnd,
"The tag has an invalid name.",
"Invalid Tag",
MB_ICONERROR);
goto fin;
case GIT_EEXISTS:
ret = SCC_E_NONSPECIFICERROR;
MessageBox(hwnd,
"The tag by that name already exists.",
"Invalid Tag",
MB_ICONERROR);
goto fin;
default:
LGitLibraryError(hwnd, "git_tag_create");
ret = SCC_E_NONSPECIFICERROR;
goto fin;
}
LGitLog(" ! Wrote tag %s as %s\n", name, git_oid_tostr_s(&tag_oid));
fin:
git_buf_dispose(&prettified_message);
if (signature != NULL) {
git_signature_free(signature);
}
return ret;
}
static SCCRTN CreateLightweightTag(LGitContext *ctx,
HWND hwnd,
const char *name,
git_commit *based_on,
BOOL force)
{
SCCRTN ret = SCC_OK;
git_oid target_oid;
switch (git_tag_create_lightweight(&target_oid, ctx->repo, name, (git_object*)based_on, force)) {
case 0:
break;
case GIT_EINVALIDSPEC:
ret = SCC_E_NONSPECIFICERROR;
MessageBox(hwnd,
"The tag has an invalid name.",
"Invalid Tag",
MB_ICONERROR);
goto fin;
case GIT_EEXISTS:
ret = SCC_E_NONSPECIFICERROR;
MessageBox(hwnd,
"The tag by that name already exists.",
"Invalid Tag",
MB_ICONERROR);
goto fin;
default:
LGitLibraryError(hwnd, "git_tag_create_lightweight");
ret = SCC_E_NONSPECIFICERROR;
goto fin;
}
LGitLog(" ! Wrote tag %s to %s\n", name, git_oid_tostr_s(&target_oid));
fin:
return ret;
}
SCCRTN LGitAddTagDialog(LGitContext *ctx, HWND hwnd)
{
LGitLog("**LGitAddTagDialog** Context=%p\n", ctx);
LGitAddTagDialogParams at_params;
ZeroMemory(&at_params, sizeof(LGitAddTagDialogParams));
at_params.ctx = ctx;
switch (DialogBoxParamW(ctx->dllInst,
MAKEINTRESOURCEW(IDD_TAG_ADD),
hwnd,
AddTagDialogProc,
(LPARAM)&at_params)) {
case 0:
case -1:
LGitLog(" ! Uh-oh, dialog error\n");
return SCC_E_NONSPECIFICERROR;
case 1:
return SCC_I_OPERATIONCANCELED;
case 2:
break;
}
/* Common stuff before we decide this is an annotated tag or not */
SCCRTN ret = SCC_OK;
git_object *object = NULL;
git_commit *commit = NULL;
/*
* XXX: Is it safe to make a branch without a commit (unborn); if so, just
* skip the init here and go to the branch create call.
*/
if (git_revparse_single(&object, ctx->repo, at_params.based_on) != 0) {
LGitLibraryError(hwnd, "git_revparse_single");
goto err;
}
if (git_object_peel((git_object**)&commit, object, GIT_OBJECT_COMMIT) != 0) {
LGitLibraryError(hwnd, "git_object_peel");
goto err;
}
/* Now decide. */
if (strlen(at_params.message) == 0) {
LGitLog(" ! Lightweight tag\n");
ret = CreateLightweightTag(ctx, hwnd, at_params.new_name, commit, at_params.force);
} else {
LGitLog(" ! Annotated tag\n");
ret = CreateAnnotatedTag(ctx, hwnd, at_params.new_name, commit, at_params.message, at_params.force);
}
err:
if (commit != NULL) {
git_commit_free(commit);
}
if (object != NULL) {
git_object_free(object);
}
return ret;
}