Skip to content

Commit 923317d

Browse files
committed
index: modernize error handling of index_insert
The current error hanling of the function `index_insert` is currently very fragile. Instead of erroring out in case an error has happened, it will instead verify that no error has happened for each statement. This makes adding new code to that function an adventurous task. Improve the situation by converting the function to use our typical `goto out` pattern.
1 parent f010b66 commit 923317d

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

src/index.c

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,57 +1337,58 @@ static int index_insert(
13371337
bool trust_mode,
13381338
bool trust_id)
13391339
{
1340-
int error = 0;
1341-
size_t path_length, position;
13421340
git_index_entry *existing, *best, *entry;
1341+
size_t path_length, position;
1342+
int error;
13431343

13441344
assert(index && entry_ptr);
13451345

13461346
entry = *entry_ptr;
13471347

1348-
/* make sure that the path length flag is correct */
1348+
/* Make sure that the path length flag is correct */
13491349
path_length = ((struct entry_internal *)entry)->pathlen;
13501350
index_entry_adjust_namemask(entry, path_length);
13511351

1352-
/* this entry is now up-to-date and should not be checked for raciness */
1352+
/* This entry is now up-to-date and should not be checked for raciness */
13531353
entry->flags_extended |= GIT_IDXENTRY_UPTODATE;
13541354

13551355
git_vector_sort(&index->entries);
13561356

1357-
/* look if an entry with this path already exists, either staged, or (if
1357+
/*
1358+
* Look if an entry with this path already exists, either staged, or (if
13581359
* this entry is a regular staged item) as the "ours" side of a conflict.
13591360
*/
13601361
index_existing_and_best(&existing, &position, &best, index, entry);
13611362

1362-
/* update the file mode */
1363+
/* Update the file mode */
13631364
entry->mode = trust_mode ?
13641365
git_index__create_mode(entry->mode) :
13651366
index_merge_mode(index, best, entry->mode);
13661367

1367-
/* canonicalize the directory name */
1368-
if (!trust_path)
1369-
error = canonicalize_directory_path(index, entry, best);
1368+
/* Canonicalize the directory name */
1369+
if (!trust_path && (error = canonicalize_directory_path(index, entry, best)) < 0)
1370+
goto out;
13701371

1371-
/* ensure that the given id exists (unless it's a submodule) */
1372-
if (!error && !trust_id && INDEX_OWNER(index) &&
1373-
(entry->mode & GIT_FILEMODE_COMMIT) != GIT_FILEMODE_COMMIT) {
1372+
/* Ensure that the given id exists (unless it's a submodule) */
1373+
if (!trust_id && INDEX_OWNER(index) &&
1374+
(entry->mode & GIT_FILEMODE_COMMIT) != GIT_FILEMODE_COMMIT) {
13741375

13751376
if (!git_object__is_valid(INDEX_OWNER(index), &entry->id,
1376-
git_object__type_from_filemode(entry->mode)))
1377+
git_object__type_from_filemode(entry->mode))) {
13771378
error = -1;
1379+
goto out;
1380+
}
13781381
}
13791382

1380-
/* look for tree / blob name collisions, removing conflicts if requested */
1381-
if (!error)
1382-
error = check_file_directory_collision(index, entry, position, replace);
1383-
1384-
if (error < 0)
1385-
/* skip changes */;
1383+
/* Look for tree / blob name collisions, removing conflicts if requested */
1384+
if ((error = check_file_directory_collision(index, entry, position, replace)) < 0)
1385+
goto out;
13861386

1387-
/* if we are replacing an existing item, overwrite the existing entry
1387+
/*
1388+
* If we are replacing an existing item, overwrite the existing entry
13881389
* and return it in place of the passed in one.
13891390
*/
1390-
else if (existing) {
1391+
if (existing) {
13911392
if (replace) {
13921393
index_entry_cpy(existing, entry);
13931394

@@ -1396,25 +1397,25 @@ static int index_insert(
13961397
}
13971398

13981399
index_entry_free(entry);
1399-
*entry_ptr = entry = existing;
1400-
}
1401-
else {
1402-
/* if replace is not requested or no existing entry exists, insert
1400+
*entry_ptr = existing;
1401+
} else {
1402+
/*
1403+
* If replace is not requested or no existing entry exists, insert
14031404
* at the sorted position. (Since we re-sort after each insert to
14041405
* check for dups, this is actually cheaper in the long run.)
14051406
*/
1406-
error = git_vector_insert_sorted(&index->entries, entry, index_no_dups);
1407+
if ((error = git_vector_insert_sorted(&index->entries, entry, index_no_dups)) < 0)
1408+
goto out;
14071409

1408-
if (error == 0) {
1409-
INSERT_IN_MAP(index, entry, &error);
1410-
}
1410+
INSERT_IN_MAP(index, entry, &error);
14111411
}
14121412

1413+
index->dirty = 1;
1414+
1415+
out:
14131416
if (error < 0) {
14141417
index_entry_free(*entry_ptr);
14151418
*entry_ptr = NULL;
1416-
} else {
1417-
index->dirty = 1;
14181419
}
14191420

14201421
return error;

0 commit comments

Comments
 (0)