7 #include "../../src/framework/Platform/CompilerDefs.h"
9 #if PLATFORM == PLATFORM_WINDOWS
12 #define pclose _pclose
13 #define snprintf _snprintf
14 #pragma warning (disable:4996)
23 char remotes
[NUM_REMOTES
][256] = {
24 "git@github.com:mangos/mangos.git",
25 "git://github.com/mangos/mangos.git" // used for fetch if present
28 bool allow_replace
= false;
30 bool do_fetch
= false;
34 char origins
[NUM_REMOTES
][256];
36 char head_message
[16384];
37 char write_file
[2048];
44 printf("+ finding path\n");
45 char cur_path
[2048], *ptr
;
46 getcwd(cur_path
, 2048);
47 int len
= strnlen(cur_path
, 2048);
49 if(cur_path
[len
-1] == '/' || cur_path
[len
-1] == '\\')
51 // we're in root, don't bother
55 // don't count the root
56 int count_fwd
= 0, count_back
= 0;
57 for(ptr
= cur_path
-1; ptr
= strchr(ptr
+1, '/'); count_fwd
++);
58 for(ptr
= cur_path
-1; ptr
= strchr(ptr
+1, '\\'); count_back
++);
59 int count
= std::max(count_fwd
, count_back
);
61 char prefix
[2048] = "", path
[2048];
62 for(int i
= 0; i
< count
; i
++)
64 snprintf(path
, 2048, "%s.git", prefix
);
68 snprintf(write_file
, 2048, "%ssrc/shared/revision_nr.h", prefix
);
71 strncat(prefix
, "../", 2048);
79 printf("+ finding origin\n");
80 if( (cmd_pipe
= popen( "git remote -v", "r" )) == NULL
)
84 while(fgets(buffer
, 256, cmd_pipe
))
86 char name
[256], remote
[256];
87 sscanf(buffer
, "%s %s", name
, remote
);
88 for(int i
= 0; i
< NUM_REMOTES
; i
++)
90 if(strcmp(remote
, remotes
[i
]) == 0)
92 strncpy(origins
[i
], name
, 256);
103 printf("+ fetching origin\n");
105 // use the public clone url if present because the private may require a password
106 sprintf(cmd
, "git fetch %s master", origins
[1][0] ? origins
[1] : origins
[0]);
107 int ret
= system(cmd
);
113 printf("+ checking fast forward\n");
115 sprintf(cmd
, "git log -n 1 --pretty=\"format:%%H\" %s/master", origins
[1][0] ? origins
[1] : origins
[0]);
116 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
120 if(!fgets(buffer
, 256, cmd_pipe
)) return false;
121 strncpy(hash
, buffer
, 256);
124 if( (cmd_pipe
= popen( "git log --pretty=\"format:%H\"", "r" )) == NULL
)
128 while(fgets(buffer
, 256, cmd_pipe
))
130 buffer
[strnlen(buffer
, 256) - 1] = '\0';
131 if(strncmp(hash
, buffer
, 256) == 0)
139 if(!found
) printf("WARNING: non-fastforward, use rebase!\n");
143 int get_rev(const char *from_msg
)
145 // accept only the rev number format, not the sql update format
147 if(sscanf(from_msg
, "[%[0123456789]]", nr_str
) != 1) return 0;
148 if(from_msg
[strlen(nr_str
)+1] != ']') return 0;
154 printf("+ finding next revision number\n");
155 // find the highest rev number on either of the remotes
156 for(int i
= 0; i
< NUM_REMOTES
; i
++)
158 if(!local
&& !origins
[i
][0]) continue;
161 if(local
) sprintf(cmd
, "git log HEAD --pretty=\"format:%%s\"");
162 else sprintf(cmd
, "git log %s/master --pretty=\"format:%%s\"", origins
[i
]);
163 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
167 while(fgets(buffer
, 256, cmd_pipe
))
169 nr
= get_rev(buffer
);
176 if(rev
> 0) printf("Found [%d].\n", rev
);
181 std::string
generateHeader(char const* rev_str
)
183 std::ostringstream newData
;
184 newData
<< "#ifndef __REVISION_NR_H__" << std::endl
;
185 newData
<< "#define __REVISION_NR_H__" << std::endl
;
186 newData
<< " #define REVISION_NR \"" << rev_str
<< "\"" << std::endl
;
187 newData
<< "#endif // __REVISION_NR_H__" << std::endl
;
188 return newData
.str();
193 printf("+ writing revision_nr.h\n");
195 sprintf(rev_str
, "%d", rev
);
196 std::string header
= generateHeader(rev_str
);
198 if(FILE* OutputFile
= fopen(write_file
,"wb"))
200 fprintf(OutputFile
,"%s", header
.c_str());
210 printf("+ finding last message on HEAD\n");
211 if( (cmd_pipe
= popen( "git log -n 1 --pretty=\"format:%s%n%n%b\"", "r" )) == NULL
)
215 while(poz
< 16384-1 && EOF
!= (head_message
[poz
++] = fgetc(cmd_pipe
)));
216 head_message
[poz
-1] = '\0';
220 if(int head_rev
= get_rev(head_message
))
224 printf("Last commit on HEAD is [%d]. Use -r to replace it with [%d].\n", head_rev
, rev
);
228 // skip the rev number in the commit
229 char *p
= strchr(head_message
, ']'), *q
= head_message
;
232 while(*p
) *q
= *p
, p
++, q
++;
242 printf("+ amending last commit\n");
244 sprintf(cmd
, "git commit --amend -F- %s", write_file
);
245 if( (cmd_pipe
= popen( cmd
, "w" )) == NULL
)
248 fprintf(cmd_pipe
, "[%d] %s", rev
, head_message
);
254 #define DO(cmd) if(!cmd) { printf("FAILED\n"); return 1; }
256 int main(int argc
, char *argv
[])
258 for(int i
= 1; i
< argc
; i
++)
260 if(argv
[i
] == NULL
) continue;
261 if(strncmp(argv
[i
], "-r", 2) == 0 || strncmp(argv
[i
], "--replace", 2) == 0)
262 allow_replace
= true;
263 if(strncmp(argv
[i
], "-l", 2) == 0 || strncmp(argv
[i
], "--local", 2) == 0)
265 if(strncmp(argv
[i
], "-f", 2) == 0 || strncmp(argv
[i
], "--fetch", 2) == 0)
267 if(strncmp(argv
[i
], "-h", 2) == 0 || strncmp(argv
[i
], "--help", 2) == 0)
269 printf("Usage: git_id [OPTION]\n");
270 printf("Generates a new rev number and updates revision_nr.h and the commit message.\n");
271 printf("Should be used just before push.\n");
272 printf(" -h, --help show the usage\n");
273 printf(" -r, --replace replace the rev number if it was already applied to the last\n");
275 printf(" -l, --local search for the highest rev number on HEAD\n");
276 printf(" -f, --fetch fetch from origin before searching for the new rev\n");
287 DO( fetch_origin() );
292 DO( find_head_msg() );
294 DO( amend_commit() );