2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "../../src/framework/Platform/CompilerDefs.h"
30 #if PLATFORM == PLATFORM_WINDOWS
33 #define pclose _pclose
34 #define snprintf _snprintf
35 #define putenv _putenv
36 #pragma warning (disable:4996)
43 #define MAX_REMOTE 256
54 #define NUM_DATABASES 3
56 char remotes
[NUM_REMOTES
][MAX_REMOTE
] = {
57 "git@github.com:mangos/mangos.git",
58 "git://github.com/mangos/mangos.git" // used for fetch if present
61 char remote_branch
[MAX_REMOTE
] = "master";
62 char rev_file
[MAX_PATH
] = "src/shared/revision_nr.h";
63 char sql_update_dir
[MAX_PATH
] = "sql/updates";
64 char new_index_file
[MAX_PATH
] = ".git/git_id_index";
66 char databases
[NUM_DATABASES
][MAX_DB
] = {
72 char db_version_table
[NUM_DATABASES
][MAX_DB
] = {
73 "character_db_version",
78 char db_sql_file
[NUM_DATABASES
][MAX_PATH
] = {
84 bool allow_replace
= false;
86 bool do_fetch
= false;
88 bool use_new_index
= true;
92 char origins
[NUM_REMOTES
][MAX_REMOTE
];
94 int last_sql_rev
[NUM_DATABASES
] = {0,0,0};
95 int last_sql_nr
[NUM_DATABASES
] = {0,0,0};
97 char head_message
[MAX_MSG
];
98 char path_prefix
[MAX_PATH
] = "";
99 char base_path
[MAX_PATH
];
100 char buffer
[MAX_BUF
];
102 char origin_hash
[MAX_HASH
];
103 char last_sql_update
[NUM_DATABASES
][MAX_PATH
];
104 char old_index_cmd
[MAX_CMD
];
105 char new_index_cmd
[MAX_CMD
];
107 std::set
<std::string
> new_sql_updates
;
113 printf("+ finding path\n");
115 char cur_path
[MAX_PATH
];
116 getcwd(cur_path
, MAX_PATH
);
117 int len
= strlen(cur_path
);
118 strncpy(base_path
, cur_path
, len
+1);
120 if(cur_path
[len
-1] == '/' || cur_path
[len
-1] == '\\')
122 // we're in root, don't bother
126 // don't count the root
127 int count_fwd
= 0, count_back
= 0;
128 for(ptr
= cur_path
-1; ptr
= strchr(ptr
+1, '/'); count_fwd
++);
129 for(ptr
= cur_path
-1; ptr
= strchr(ptr
+1, '\\'); count_back
++);
130 int count
= std::max(count_fwd
, count_back
);
133 for(int i
= 0; i
< count
; i
++)
135 snprintf(path
, MAX_PATH
, "%s.git", path_prefix
);
141 strncat(path_prefix
, "../", MAX_PATH
);
143 ptr
= strrchr(base_path
, '\\');
147 ptr
= strrchr(base_path
, '/');
157 printf("+ finding origin\n");
158 if( (cmd_pipe
= popen( "git remote -v", "r" )) == NULL
)
162 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
164 char name
[256], remote
[MAX_REMOTE
];
165 sscanf(buffer
, "%s %s", name
, remote
);
166 for(int i
= 0; i
< NUM_REMOTES
; i
++)
168 if(strcmp(remote
, remotes
[i
]) == 0)
170 strncpy(origins
[i
], name
, MAX_REMOTE
);
181 printf("+ fetching origin\n");
182 // use the public clone url if present because the private may require a password
183 snprintf(cmd
, MAX_CMD
, "git fetch %s %s", (origins
[1][0] ? origins
[1] : origins
[0]), remote_branch
);
184 int ret
= system(cmd
);
190 printf("+ checking fast forward\n");
191 snprintf(cmd
, MAX_CMD
, "git log -n 1 --pretty=\"format:%%H\" %s/%s", (origins
[1][0] ? origins
[1] : origins
[0]), remote_branch
);
192 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
195 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) return false;
196 strncpy(origin_hash
, buffer
, MAX_HASH
);
199 if( (cmd_pipe
= popen( "git log --pretty=\"format:%H\"", "r" )) == NULL
)
203 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
205 buffer
[strlen(buffer
) - 1] = '\0';
206 if(strncmp(origin_hash
, buffer
, MAX_BUF
) == 0)
216 // with fetch you still get the latest rev, you just rebase afterwards and push
217 // without it you may not get the right rev
218 if(do_fetch
) printf("WARNING: non-fastforward, use rebase!\n");
219 else { printf("ERROR: non-fastforward, use rebase!\n"); return false; }
224 int get_rev(const char *from_msg
)
226 // accept only the rev number format, not the sql update format
228 if(sscanf(from_msg
, "[%[0123456789]]", nr_str
) != 1) return 0;
229 if(from_msg
[strlen(nr_str
)+1] != ']') return 0;
235 printf("+ finding next revision number\n");
236 // find the highest rev number on either of the remotes
237 for(int i
= 0; i
< NUM_REMOTES
; i
++)
239 if(!local
&& !origins
[i
][0]) continue;
241 if(local
) snprintf(cmd
, MAX_CMD
, "git log HEAD --pretty=\"format:%%s\"");
242 else sprintf(cmd
, "git log %s/%s --pretty=\"format:%%s\"", origins
[i
], remote_branch
);
243 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
247 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
249 nr
= get_rev(buffer
);
256 if(rev
> 0) printf("Found [%d].\n", rev
);
261 std::string
generateHeader(char const* rev_str
)
263 std::ostringstream newData
;
264 newData
<< "#ifndef __REVISION_NR_H__" << std::endl
;
265 newData
<< "#define __REVISION_NR_H__" << std::endl
;
266 newData
<< " #define REVISION_NR \"" << rev_str
<< "\"" << std::endl
;
267 newData
<< "#endif // __REVISION_NR_H__" << std::endl
;
268 return newData
.str();
271 void system_switch_index(const char *cmd
)
273 // do the command for the original index and then for the new index
274 // both need to be updated with the changes before commit
275 // but the new index will contains only the desired changes
276 // while the old may contain others
278 if(!use_new_index
) return;
279 if(putenv(new_index_cmd
) != 0) return;
281 if(putenv(old_index_cmd
) != 0) return;
286 printf("+ writing revision_nr.h\n");
288 sprintf(rev_str
, "%d", rev
);
289 std::string header
= generateHeader(rev_str
);
291 char prefixed_file
[MAX_PATH
];
292 snprintf(prefixed_file
, MAX_PATH
, "%s%s", path_prefix
, rev_file
);
294 if(FILE* OutputFile
= fopen(prefixed_file
, "wb"))
296 fprintf(OutputFile
,"%s", header
.c_str());
299 // add the file to both indices, to be committed later
300 snprintf(cmd
, MAX_CMD
, "git add %s", prefixed_file
);
301 system_switch_index(cmd
);
311 printf("+ finding last message on HEAD\n");
312 if( (cmd_pipe
= popen( "git log -n 1 --pretty=\"format:%s%n%n%b\"", "r" )) == NULL
)
316 while(poz
< 16384-1 && EOF
!= (head_message
[poz
++] = fgetc(cmd_pipe
)));
317 head_message
[poz
-1] = '\0';
321 if(int head_rev
= get_rev(head_message
))
325 printf("Last commit on HEAD is [%d]. Use -r to replace it with [%d].\n", head_rev
, rev
);
329 // skip the rev number in the commit
330 char *p
= strchr(head_message
, ']'), *q
= head_message
;
333 while(*p
) *q
= *p
, p
++, q
++;
343 printf("+ amending last commit\n");
345 // commit the contents of the (new) index
346 if(use_new_index
&& putenv(new_index_cmd
) != 0) return false;
347 snprintf(cmd
, MAX_CMD
, "git commit --amend -F-");
348 if( (cmd_pipe
= popen( cmd
, "w" )) == NULL
)
351 fprintf(cmd_pipe
, "[%d] %s", rev
, head_message
);
353 if(use_new_index
&& putenv(old_index_cmd
) != 0) return false;
358 struct sql_update_info
368 bool get_sql_update_info(const char *buffer
, sql_update_info
&info
)
370 info
.table
[0] = '\0';
372 if(sscanf(buffer
, "%d_%d_%d", &dummy
[0], &dummy
[1], &dummy
[2]) == 3)
375 if(sscanf(buffer
, "%d_%d_%[^_]_%[^.].sql", &info
.rev
, &info
.nr
, info
.db
, info
.table
) != 4 &&
376 sscanf(buffer
, "%d_%d_%[^.].sql", &info
.rev
, &info
.nr
, info
.db
) != 3)
378 info
.rev
= 0; // this may be set by the first scans, even if they fail
379 if(sscanf(buffer
, "%d_%[^_]_%[^.].sql", &info
.nr
, info
.db
, info
.table
) != 3 &&
380 sscanf(buffer
, "%d_%[^.].sql", &info
.nr
, info
.db
) != 2)
384 for(info
.db_idx
= 0; info
.db_idx
< NUM_DATABASES
; info
.db_idx
++)
385 if(strncmp(info
.db
, databases
[info
.db_idx
], MAX_DB
) == 0) break;
386 info
.has_table
= (info
.table
[0] != '\0');
390 bool find_sql_updates()
392 printf("+ finding new sql updates on HEAD\n");
393 // add all updates from HEAD
394 snprintf(cmd
, MAX_CMD
, "git show HEAD:%s", sql_update_dir
);
395 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
398 // skip first two lines
399 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) { pclose(cmd_pipe
); return false; }
400 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) { pclose(cmd_pipe
); return false; }
402 sql_update_info info
;
404 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
406 buffer
[strlen(buffer
) - 1] = '\0';
407 if(!get_sql_update_info(buffer
, info
)) continue;
409 if(info
.db_idx
== NUM_DATABASES
)
411 if(info
.rev
> 0) printf("WARNING: incorrect database name for sql update %s\n", buffer
);
415 new_sql_updates
.insert(buffer
);
420 // remove updates from the last commit also found on origin
421 snprintf(cmd
, MAX_CMD
, "git show %s:%s", origin_hash
, sql_update_dir
);
422 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
425 // skip first two lines
426 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) { pclose(cmd_pipe
); return false; }
427 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) { pclose(cmd_pipe
); return false; }
429 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
431 buffer
[strlen(buffer
) - 1] = '\0';
432 if(!get_sql_update_info(buffer
, info
)) continue;
434 // find the old update with the highest rev for each database
435 // (will be the required version for the new update)
436 std::set
<std::string
>::iterator itr
= new_sql_updates
.find(buffer
);
437 if(itr
!= new_sql_updates
.end() )
439 if(info
.rev
> 0 && (info
.rev
> last_sql_rev
[info
.db_idx
] ||
440 (info
.rev
== last_sql_rev
[info
.db_idx
] && info
.nr
> last_sql_nr
[info
.db_idx
])))
442 last_sql_rev
[info
.db_idx
] = info
.rev
;
443 last_sql_nr
[info
.db_idx
] = info
.nr
;
444 sscanf(buffer
, "%[^.]", last_sql_update
[info
.db_idx
]);
446 new_sql_updates
.erase(itr
);
452 if(!new_sql_updates
.empty())
454 for(std::set
<std::string
>::iterator itr
= new_sql_updates
.begin(); itr
!= new_sql_updates
.end(); ++itr
)
455 printf("%s\n", itr
->c_str());
458 printf("WARNING: no new sql updates found.\n");
463 bool copy_file(const char *src_file
, const char *dst_file
)
465 FILE * fin
= fopen( src_file
, "rb" );
466 if(!fin
) return false;
467 FILE * fout
= fopen( dst_file
, "wb" );
468 if(!fout
) { fclose(fin
); return false; }
470 for(char c
= getc(fin
); !feof(fin
); putc(c
, fout
), c
= getc(fin
));
477 bool convert_sql_updates()
479 if(new_sql_updates
.empty()) return true;
481 printf("+ converting sql updates\n");
483 // rename the sql update files and add the required update statement
484 for(std::set
<std::string
>::iterator itr
= new_sql_updates
.begin(); itr
!= new_sql_updates
.end(); ++itr
)
486 sql_update_info info
;
487 if(!get_sql_update_info(itr
->c_str(), info
)) return false;
488 if(info
.db_idx
== NUM_DATABASES
) return false;
490 // generating the new name should work for updates with or without a rev
491 char src_file
[MAX_PATH
], new_name
[MAX_PATH
], dst_file
[MAX_PATH
];
492 snprintf(src_file
, MAX_PATH
, "%s%s/%s", path_prefix
, sql_update_dir
, itr
->c_str());
493 snprintf(new_name
, MAX_PATH
, "%d_%0*d_%s%s%s", rev
, 2, info
.nr
, info
.db
, info
.has_table
? "_" : "", info
.table
);
494 snprintf(dst_file
, MAX_PATH
, "%s%s/%s.sql", path_prefix
, sql_update_dir
, new_name
);
496 FILE * fin
= fopen( src_file
, "r" );
497 if(!fin
) return false;
498 FILE * fout
= fopen( dst_file
, "w" );
499 if(!fout
) { fclose(fin
); return false; }
501 // add the update requirements
502 fprintf(fout
, "ALTER TABLE %s CHANGE COLUMN required_%s required_%s bit;\n\n",
503 db_version_table
[info
.db_idx
], last_sql_update
[info
.db_idx
], new_name
);
505 // skip the first one or two lines from the input
506 // if it already contains update requirements
507 if(fgets(buffer
, MAX_BUF
, fin
))
510 if(sscanf(buffer
, "ALTER TABLE %s CHANGE COLUMN required_%s required_%s bit", dummy
, dummy
, dummy
) == 3)
512 if(fgets(buffer
, MAX_BUF
, fin
) && buffer
[0] != '\n')
519 // copy the rest of the file
521 while( (c
= getc(fin
)) != EOF
)
527 // rename the file in git
528 snprintf(cmd
, MAX_CMD
, "git add %s", dst_file
);
529 system_switch_index(cmd
);
530 snprintf(cmd
, MAX_CMD
, "git rm --quiet %s", src_file
);
531 system_switch_index(cmd
);
533 // update the last sql update for the current database
534 strncpy(last_sql_update
[info
.db_idx
], new_name
, MAX_PATH
);
540 bool generate_sql_makefile()
542 if(new_sql_updates
.empty()) return true;
544 // find all files in the update dir
545 snprintf(cmd
, MAX_CMD
, "git show HEAD:%s", sql_update_dir
);
546 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
549 // skip first two lines
550 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) { pclose(cmd_pipe
); return false; }
551 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
)) { pclose(cmd_pipe
); return false; }
553 char newname
[MAX_PATH
];
554 std::set
<std::string
> file_list
;
555 sql_update_info info
;
557 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
559 buffer
[strlen(buffer
) - 1] = '\0';
560 if(buffer
[strlen(buffer
) - 1] != '/' &&
561 strncmp(buffer
, "Makefile.am", MAX_BUF
) != 0)
563 if(new_sql_updates
.find(buffer
) != new_sql_updates
.end())
565 if(!get_sql_update_info(buffer
, info
)) return false;
566 snprintf(newname
, MAX_PATH
, "%d_%0*d_%s%s%s.sql", rev
, 2, info
.nr
, info
.db
, info
.has_table
? "_" : "", info
.table
);
567 file_list
.insert(newname
);
570 file_list
.insert(buffer
);
576 // write the makefile
577 char file_name
[MAX_PATH
];
578 snprintf(file_name
, MAX_PATH
, "%s%s/Makefile.am", path_prefix
, sql_update_dir
);
579 FILE *fout
= fopen(file_name
, "w");
580 if(!fout
) { pclose(cmd_pipe
); return false; }
583 "# Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>\n"
585 "# This program is free software; you can redistribute it and/or modify\n"
586 "# it under the terms of the GNU General Public License as published by\n"
587 "# the Free Software Foundation; either version 2 of the License, or\n"
588 "# (at your option) any later version.\n"
590 "# This program is distributed in the hope that it will be useful,\n"
591 "# but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
592 "# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
593 "# GNU General Public License for more details.\n"
595 "# You should have received a copy of the GNU General Public License\n"
596 "# along with this program; if not, write to the Free Software\n"
597 "# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
599 "## Process this file with automake to produce Makefile.in\n"
601 "## Sub-directories to parse\n"
603 "## Change installation location\n"
604 "# datadir = mangos/%s\n"
605 "pkgdatadir = $(datadir)/mangos/%s\n"
607 "## Files to be installed\n"
608 "# Install basic SQL files to datadir\n"
609 "pkgdata_DATA = \\\n",
610 sql_update_dir
, sql_update_dir
613 for(std::set
<std::string
>::iterator itr
= file_list
.begin(), next
; itr
!= file_list
.end(); ++itr
)
616 fprintf(fout
, "\t%s%s\n", itr
->c_str(), next
== file_list
.end() ? "" : " \\");
620 "\n## Additional files to include when running 'make dist'\n"
621 "# SQL update files, to upgrade database schema from older revisions\n"
625 for(std::set
<std::string
>::iterator itr
= file_list
.begin(), next
; itr
!= file_list
.end(); ++itr
)
628 fprintf(fout
, "\t%s%s\n", itr
->c_str(), next
== file_list
.end() ? "" : " \\");
633 snprintf(cmd
, MAX_CMD
, "git add %s%s/Makefile.am", path_prefix
, sql_update_dir
);
634 system_switch_index(cmd
);
639 bool change_sql_database()
641 if(new_sql_updates
.empty()) return true;
642 printf("+ changing database sql files\n");
644 // rename the database files, copy their contents back
645 // and change the required update line
646 for(int i
= 0; i
< NUM_DATABASES
; i
++)
648 if(last_sql_update
[i
][0] == '\0') continue;
650 char old_file
[MAX_PATH
], tmp_file
[MAX_PATH
], dummy
[MAX_BUF
];
652 snprintf(old_file
, MAX_PATH
, "%s%s", path_prefix
, db_sql_file
[i
]);
653 snprintf(tmp_file
, MAX_PATH
, "%s%stmp", path_prefix
, db_sql_file
[i
]);
655 rename(old_file
, tmp_file
);
657 FILE *fin
= fopen( tmp_file
, "r" );
658 if(!fin
) return false;
659 FILE *fout
= fopen( old_file
, "w" );
660 if(!fout
) return false;
662 snprintf(dummy
, MAX_CMD
, "CREATE TABLE `%s` (\n", db_version_table
[i
]);
663 while(fgets(buffer
, MAX_BUF
, fin
))
666 if(strncmp(buffer
, dummy
, MAX_BUF
) == 0)
672 if(!fgets(buffer
, MAX_BUF
, fin
)) return false;
673 if(sscanf(buffer
, " `required_%s`", dummy
) == 1) break;
677 fprintf(fout
, " `required_%s` bit(1) default NULL\n", last_sql_update
[i
]);
678 while(fgets(buffer
, MAX_BUF
, fin
))
685 snprintf(cmd
, MAX_CMD
, "git add %s", old_file
);
686 system_switch_index(cmd
);
691 bool change_sql_history()
693 snprintf(cmd
, MAX_CMD
, "git log HEAD --pretty=\"format:%%H\"");
694 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
697 std::list
<std::string
> hashes
;
698 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
700 buffer
[strlen(buffer
) - 1] = '\0';
701 if(strncmp(origin_hash
, buffer
, MAX_HASH
) == 0)
704 hashes
.push_back(buffer
);
707 if(hashes
.empty()) return false; // must have at least one commit
708 if(hashes
.size() < 2) return true; // only one commit, ok but nothing to do
710 snprintf(cmd
, MAX_CMD
, "git reset --hard %s", origin_hash
);
713 for(std::list
<std::string
>::reverse_iterator next
= hashes
.rbegin(), itr
= next
++; next
!= hashes
.rend(); ++itr
, ++next
)
715 // stage the changes from the orignal commit
716 snprintf(cmd
, MAX_CMD
, "git cherry-pick -n %s", itr
->c_str());
719 // remove changed and deleted files
720 snprintf(cmd
, MAX_CMD
, "git checkout HEAD %s%s", path_prefix
, sql_update_dir
);
723 // remove the newly added files
724 snprintf(cmd
, MAX_CMD
, "git diff --cached --diff-filter=A --name-only %s%s", path_prefix
, sql_update_dir
);
725 if( (cmd_pipe
= popen( cmd
, "r" )) == NULL
)
728 while(fgets(buffer
, MAX_BUF
, cmd_pipe
))
730 buffer
[strlen(buffer
) - 1] = '\0';
731 snprintf(cmd
, MAX_CMD
, "git rm -f --quiet %s%s", path_prefix
, buffer
);
737 // make a commit with the same author and message as the original one
739 snprintf(cmd
, MAX_CMD
, "git commit -C %s", itr
->c_str());
743 snprintf(cmd
, MAX_CMD
, "git cherry-pick %s", hashes
.begin()->c_str());
749 bool prepare_new_index()
751 if(!use_new_index
) return true;
753 // only use a new index if there are staged changes that should be preserved
754 if( (cmd_pipe
= popen( "git diff --cached", "r" )) == NULL
)
757 if(!fgets(buffer
, MAX_BUF
, cmd_pipe
))
759 use_new_index
= false;
766 printf("+ preparing new index\n");
768 // copy the existing index file to a new one
769 char src_file
[MAX_PATH
], dst_file
[MAX_PATH
];
771 char *old_index
= getenv("GIT_INDEX_FILE");
772 if(old_index
) strncpy(src_file
, old_index
, MAX_PATH
);
773 else snprintf(src_file
, MAX_PATH
, "%s.git/index", path_prefix
);
774 snprintf(dst_file
, MAX_PATH
, "%s%s", path_prefix
, new_index_file
);
776 if(!copy_file(src_file
, dst_file
)) return false;
778 // doesn't seem to work with path_prefix
779 snprintf(new_index_cmd
, MAX_CMD
, "GIT_INDEX_FILE=%s/%s", base_path
, new_index_file
);
780 if(putenv(new_index_cmd
) != 0) return false;
782 // clear the new index
783 system("git reset -q --mixed HEAD");
785 // revert to old index
786 snprintf(old_index_cmd
, MAX_CMD
, "GIT_INDEX_FILE=");
787 if(putenv(old_index_cmd
) != 0) return false;
791 bool cleanup_new_index()
793 if(!use_new_index
) return true;
794 printf("+ cleaning up the new index\n");
795 char idx_file
[MAX_PATH
];
796 snprintf(idx_file
, MAX_PATH
, "%s%s", path_prefix
, new_index_file
);
801 #define DO(cmd) if(!cmd) { printf("FAILED\n"); return 1; }
803 int main(int argc
, char *argv
[])
805 for(int i
= 1; i
< argc
; i
++)
807 if(argv
[i
] == NULL
) continue;
808 if(strncmp(argv
[i
], "-r", 2) == 0 || strncmp(argv
[i
], "--replace", 9) == 0)
809 allow_replace
= true;
810 else if(strncmp(argv
[i
], "-l", 2) == 0 || strncmp(argv
[i
], "--local", 7) == 0)
812 else if(strncmp(argv
[i
], "-f", 2) == 0 || strncmp(argv
[i
], "--fetch", 7) == 0)
814 else if(strncmp(argv
[i
], "-s", 2) == 0 || strncmp(argv
[i
], "--sql", 5) == 0)
816 else if(strncmp(argv
[i
], "--branch=", 9) == 0)
817 snprintf(remote_branch
, MAX_REMOTE
, "%s", argv
[i
] + 9);
818 else if(strncmp(argv
[i
], "-h", 2) == 0 || strncmp(argv
[i
], "--help", 6) == 0)
820 printf("Usage: git_id [OPTION]\n");
821 printf("Generates a new rev number and updates revision_nr.h and the commit message.\n");
822 printf("Should be used just before push.\n");
823 printf(" -h, --help show the usage\n");
824 printf(" -r, --replace replace the rev number if it was already applied\n");
825 printf(" to the last commit\n");
826 printf(" -l, --local search for the highest rev number on HEAD\n");
827 printf(" -f, --fetch fetch from origin before searching for the new rev\n");
828 printf(" -s, --sql search for new sql updates and do all of the changes\n");
829 printf(" for the new rev\n");
830 printf(" --branch=BRANCH specify which remote branch to use\n");
840 DO( fetch_origin() );
844 DO( find_head_msg() );
846 DO( find_sql_updates() );
847 DO( prepare_new_index() );
851 DO( convert_sql_updates() );
852 DO( generate_sql_makefile() );
853 DO( change_sql_database() );
855 DO( amend_commit() );
856 DO( cleanup_new_index() );
858 // DO( change_sql_history() );