|
|
@@ -683,6 +683,8 @@ public class DirCacheCheckout { |
|
|
|
} |
|
|
|
|
|
|
|
if (i == null) { |
|
|
|
// Nothing in Index |
|
|
|
// At least one of Head, Index, Merge is not empty |
|
|
|
// make sure not to overwrite untracked files |
|
|
|
if (f != null) { |
|
|
|
// A submodule is not a file. We should ignore it |
|
|
@@ -711,17 +713,37 @@ public class DirCacheCheckout { |
|
|
|
*/ |
|
|
|
|
|
|
|
if (h == null) |
|
|
|
// Nothing in Head |
|
|
|
// Nothing in Index |
|
|
|
// At least one of Head, Index, Merge is not empty |
|
|
|
// -> only Merge contains something for this path. Use it! |
|
|
|
// Potentially update the file |
|
|
|
update(name, mId, mMode); // 1 |
|
|
|
else if (m == null) |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
// Nothing in Index |
|
|
|
// -> only Head contains something for this path and it should |
|
|
|
// be deleted. Potentially removes the file! |
|
|
|
remove(name); // 2 |
|
|
|
else { // 3 |
|
|
|
// Something in Merge |
|
|
|
// Something in Head |
|
|
|
// Nothing in Index |
|
|
|
// -> Head and Merge contain something (maybe not the same) and |
|
|
|
// in the index there is nothing (e.g. 'git rm ...' was |
|
|
|
// called before). Ignore the cached deletion and use what we |
|
|
|
// find in Merge. Potentially updates the file. |
|
|
|
if (equalIdAndMode(hId, hMode, mId, mMode)) |
|
|
|
keep(dce); |
|
|
|
else |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Something in Index |
|
|
|
if (h == null) { |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
/** |
|
|
|
* <pre> |
|
|
|
* clean I==H I==M H M Result |
|
|
@@ -737,17 +759,54 @@ public class DirCacheCheckout { |
|
|
|
*/ |
|
|
|
|
|
|
|
if (m == null || equalIdAndMode(mId, mMode, iId, iMode)) { |
|
|
|
// Merge contains nothing or the same as Index |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
if (m==null && walk.isDirectoryFileConflict()) { |
|
|
|
// Nothing in Merge and current path is part of |
|
|
|
// File/Folder conflict |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
if (dce != null |
|
|
|
&& (f == null || f.isModified(dce, true))) |
|
|
|
// No file or file is dirty |
|
|
|
// Nothing in Merge and current path is part of |
|
|
|
// File/Folder conflict |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
// -> File folder conflict and Merge wants this |
|
|
|
// path to be removed. Since the file is dirty |
|
|
|
// report a conflict |
|
|
|
conflict(name, dce, h, m); |
|
|
|
else |
|
|
|
// A file is present and file is not dirty |
|
|
|
// Nothing in Merge and current path is part of |
|
|
|
// File/Folder conflict |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
// -> File folder conflict and Merge wants this path |
|
|
|
// to be removed. Since the file is not dirty remove |
|
|
|
// file and index entry |
|
|
|
remove(name); |
|
|
|
} else |
|
|
|
// Something in Merge or current path is not part of |
|
|
|
// File/Folder conflict |
|
|
|
// Merge contains nothing or the same as Index |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
// -> Merge contains nothing new. Keep the index. |
|
|
|
keep(dce); |
|
|
|
} else |
|
|
|
// Merge contains something and it is not the same as Index |
|
|
|
// Nothing in Head |
|
|
|
// Something in Index |
|
|
|
// -> Index contains something new (different from Head) |
|
|
|
// and Merge is different from Index. Report a conflict |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} else if (m == null) { |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
// Something in Index |
|
|
|
|
|
|
|
/** |
|
|
|
* <pre> |
|
|
@@ -761,36 +820,115 @@ public class DirCacheCheckout { |
|
|
|
*/ |
|
|
|
|
|
|
|
if (iMode == FileMode.GITLINK) { |
|
|
|
// A submodule in Index |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
// Submodules that disappear from the checkout must |
|
|
|
// be removed from the index, but not deleted from disk. |
|
|
|
remove(name); |
|
|
|
} else { |
|
|
|
// Something different from a submodule in Index |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
if (equalIdAndMode(hId, hMode, iId, iMode)) { |
|
|
|
// Index contains the same as Head |
|
|
|
// Something different from a submodule in Index |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
if (f == null || f.isModified(dce, true)) |
|
|
|
// file is dirty |
|
|
|
// Index contains the same as Head |
|
|
|
// Something different from a submodule in Index |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
// -> file is dirty but is should be removed. That's |
|
|
|
// a conflict |
|
|
|
conflict(name, dce, h, m); |
|
|
|
else |
|
|
|
// file doesn't exist or is clean |
|
|
|
// Index contains the same as Head |
|
|
|
// Something different from a submodule in Index |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
// -> Remove from index and delete the file |
|
|
|
remove(name); |
|
|
|
} else |
|
|
|
// Index contains something different from Head |
|
|
|
// Something different from a submodule in Index |
|
|
|
// Nothing in Merge |
|
|
|
// Something in Head |
|
|
|
// -> Something new is in index (and maybe even on the |
|
|
|
// filesystem). But Merge wants the path to be removed. |
|
|
|
// Report a conflict |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Something in Merge |
|
|
|
// Something in Head |
|
|
|
// Something in Index |
|
|
|
if (!equalIdAndMode(hId, hMode, mId, mMode) |
|
|
|
&& !equalIdAndMode(hId, hMode, iId, iMode) |
|
|
|
&& !equalIdAndMode(mId, mMode, iId, iMode)) |
|
|
|
// All three contents in Head, Merge, Index differ from each |
|
|
|
// other |
|
|
|
// -> All contents differ. Report a conflict. |
|
|
|
conflict(name, dce, h, m); |
|
|
|
else if (equalIdAndMode(hId, hMode, iId, iMode) |
|
|
|
else |
|
|
|
// At least two of the contents of Head, Index, Merge |
|
|
|
// are the same |
|
|
|
// Something in Merge |
|
|
|
// Something in Head |
|
|
|
// Something in Index |
|
|
|
|
|
|
|
if (equalIdAndMode(hId, hMode, iId, iMode) |
|
|
|
&& !equalIdAndMode(mId, mMode, iId, iMode)) { |
|
|
|
// Head contains the same as Index. Merge differs |
|
|
|
// Something in Merge |
|
|
|
|
|
|
|
// For submodules just update the index with the new SHA-1 |
|
|
|
if (dce != null |
|
|
|
&& FileMode.GITLINK.equals(dce.getFileMode())) { |
|
|
|
// Index and Head contain the same submodule. Merge |
|
|
|
// differs |
|
|
|
// Something in Merge |
|
|
|
// -> Nothing new in index. Move to merge. |
|
|
|
// Potentially updates the file |
|
|
|
|
|
|
|
// TODO check that we don't overwrite some unsaved |
|
|
|
// file content |
|
|
|
update(name, mId, mMode); |
|
|
|
} else if (dce != null |
|
|
|
&& (f == null || f.isModified(dce, true))) { |
|
|
|
// File doesn't exist or is dirty |
|
|
|
// Head and Index don't contain a submodule |
|
|
|
// Head contains the same as Index. Merge differs |
|
|
|
// Something in Merge |
|
|
|
// -> Merge wants the index and file to be updated |
|
|
|
// but the file is dirty. Report a conflict |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} else { |
|
|
|
// File exists and is clean |
|
|
|
// Head and Index don't contain a submodule |
|
|
|
// Head contains the same as Index. Merge differs |
|
|
|
// Something in Merge |
|
|
|
// -> Standard case when switching between branches: |
|
|
|
// Nothing new in index but something different in |
|
|
|
// Merge. Update index and file |
|
|
|
update(name, mId, mMode); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Head differs from index or merge is same as index |
|
|
|
// At least two of the contents of Head, Index, Merge |
|
|
|
// are the same |
|
|
|
// Something in Merge |
|
|
|
// Something in Head |
|
|
|
// Something in Index |
|
|
|
|
|
|
|
// Can be formulated as: Either all three states are |
|
|
|
// equal or Merge is equal to Head or Index and differs |
|
|
|
// to the other one. |
|
|
|
// -> In all three cases we don't touch index and file. |
|
|
|
|
|
|
|
keep(dce); |
|
|
|
} |
|
|
|
} |