|
|
@ -683,6 +683,8 @@ public class DirCacheCheckout { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (i == null) { |
|
|
|
if (i == null) { |
|
|
|
|
|
|
|
// Nothing in Index
|
|
|
|
|
|
|
|
// At least one of Head, Index, Merge is not empty
|
|
|
|
// make sure not to overwrite untracked files
|
|
|
|
// make sure not to overwrite untracked files
|
|
|
|
if (f != null) { |
|
|
|
if (f != null) { |
|
|
|
// A submodule is not a file. We should ignore it
|
|
|
|
// A submodule is not a file. We should ignore it
|
|
|
@ -711,17 +713,37 @@ public class DirCacheCheckout { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if (h == null) |
|
|
|
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
|
|
|
|
update(name, mId, mMode); // 1
|
|
|
|
else if (m == null) |
|
|
|
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
|
|
|
|
remove(name); // 2
|
|
|
|
else { // 3
|
|
|
|
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)) |
|
|
|
if (equalIdAndMode(hId, hMode, mId, mMode)) |
|
|
|
keep(dce); |
|
|
|
keep(dce); |
|
|
|
else |
|
|
|
else |
|
|
|
conflict(name, dce, h, m); |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
// Something in Index
|
|
|
|
if (h == null) { |
|
|
|
if (h == null) { |
|
|
|
|
|
|
|
// Nothing in Head
|
|
|
|
|
|
|
|
// Something in Index
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* <pre> |
|
|
|
* <pre> |
|
|
|
* clean I==H I==M H M Result |
|
|
|
* clean I==H I==M H M Result |
|
|
@ -737,17 +759,54 @@ public class DirCacheCheckout { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if (m == null || equalIdAndMode(mId, mMode, iId, iMode)) { |
|
|
|
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()) { |
|
|
|
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 |
|
|
|
if (dce != null |
|
|
|
&& (f == null || f.isModified(dce, true))) |
|
|
|
&& (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); |
|
|
|
conflict(name, dce, h, m); |
|
|
|
else |
|
|
|
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); |
|
|
|
remove(name); |
|
|
|
} else |
|
|
|
} 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); |
|
|
|
keep(dce); |
|
|
|
} else |
|
|
|
} 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); |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} else if (m == null) { |
|
|
|
} else if (m == null) { |
|
|
|
|
|
|
|
// Nothing in Merge
|
|
|
|
|
|
|
|
// Something in Head
|
|
|
|
|
|
|
|
// Something in Index
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* <pre> |
|
|
|
* <pre> |
|
|
@ -761,36 +820,115 @@ public class DirCacheCheckout { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if (iMode == FileMode.GITLINK) { |
|
|
|
if (iMode == FileMode.GITLINK) { |
|
|
|
|
|
|
|
// A submodule in Index
|
|
|
|
|
|
|
|
// Nothing in Merge
|
|
|
|
|
|
|
|
// Something in Head
|
|
|
|
// Submodules that disappear from the checkout must
|
|
|
|
// Submodules that disappear from the checkout must
|
|
|
|
// be removed from the index, but not deleted from disk.
|
|
|
|
// be removed from the index, but not deleted from disk.
|
|
|
|
remove(name); |
|
|
|
remove(name); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
// Something different from a submodule in Index
|
|
|
|
|
|
|
|
// Nothing in Merge
|
|
|
|
|
|
|
|
// Something in Head
|
|
|
|
if (equalIdAndMode(hId, hMode, iId, iMode)) { |
|
|
|
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)) |
|
|
|
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); |
|
|
|
conflict(name, dce, h, m); |
|
|
|
else |
|
|
|
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); |
|
|
|
remove(name); |
|
|
|
} else |
|
|
|
} 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); |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
// Something in Merge
|
|
|
|
|
|
|
|
// Something in Head
|
|
|
|
|
|
|
|
// Something in Index
|
|
|
|
if (!equalIdAndMode(hId, hMode, mId, mMode) |
|
|
|
if (!equalIdAndMode(hId, hMode, mId, mMode) |
|
|
|
&& !equalIdAndMode(hId, hMode, iId, iMode) |
|
|
|
&& !equalIdAndMode(hId, hMode, iId, iMode) |
|
|
|
&& !equalIdAndMode(mId, mMode, 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); |
|
|
|
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)) { |
|
|
|
&& !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
|
|
|
|
// For submodules just update the index with the new SHA-1
|
|
|
|
if (dce != null |
|
|
|
if (dce != null |
|
|
|
&& FileMode.GITLINK.equals(dce.getFileMode())) { |
|
|
|
&& 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); |
|
|
|
update(name, mId, mMode); |
|
|
|
} else if (dce != null |
|
|
|
} else if (dce != null |
|
|
|
&& (f == null || f.isModified(dce, true))) { |
|
|
|
&& (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); |
|
|
|
conflict(name, dce, h, m); |
|
|
|
} else { |
|
|
|
} 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); |
|
|
|
update(name, mId, mMode); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} 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); |
|
|
|
keep(dce); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|