Browse Source
Currently there is no way to determine the precise changes done to the working tree by a JGit command. Only the CheckoutCommand actually provides access to the lists of modified, deleted, and to-be-deleted files, but those lists may be inaccurate (since they are determined up-front before the working tree is modified) if the actual checkout then fails halfway through. Moreover, other JGit commands that modify the working tree do not offer any way to figure out which files were changed. This poses problems for EGit, which may need to refresh parts of the Eclipse workspace when JGit has done java.io file operations. Provide the foundations for better file change tracking: the working tree is modified exclusively in DirCacheCheckout. Make it emit a new type of RepositoryEvent that lists all files that were modified or deleted, even if the checkout failed halfway through. We update the 'updated' and 'removed' lists determined up-front in case of file system problems to reflect the actual state of changes made. EGit thus can register a listener for these events and then knows exactly which parts of the Eclipse workspace may need to be refreshed. Two commands manage checking out individual DirCacheEntries themselves: checkout specific paths, and applying a stash with untracked files. Make those two also emit such a new WorkingTreeModifiedEvent. Furthermore, merges may modify files, and clean, rm, and stash create may delete files. CQ: 13969 Bug: 500106 Change-Id: I7a100aee315791fa1201f43bbad61fbae60b35cb Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>stable-4.9
Thomas Wolf
7 years ago
committed by
Matthias Sohn
14 changed files with 1253 additions and 492 deletions
@ -0,0 +1,108 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch> |
||||||
|
* and other copyright owners as documented in the project's IP log. |
||||||
|
* |
||||||
|
* This program and the accompanying materials are made available |
||||||
|
* under the terms of the Eclipse Distribution License v1.0 which |
||||||
|
* accompanies this distribution, is reproduced below, and is |
||||||
|
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||||
|
* |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or |
||||||
|
* without modification, are permitted provided that the following |
||||||
|
* conditions are met: |
||||||
|
* |
||||||
|
* - Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* - Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following |
||||||
|
* disclaimer in the documentation and/or other materials provided |
||||||
|
* with the distribution. |
||||||
|
* |
||||||
|
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||||
|
* names of its contributors may be used to endorse or promote |
||||||
|
* products derived from this software without specific prior |
||||||
|
* written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.eclipse.jgit.events; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals; |
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
|
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.HashSet; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
/** |
||||||
|
* A {@link WorkingTreeModifiedListener} that can be used in tests to check |
||||||
|
* expected events. |
||||||
|
*/ |
||||||
|
public class ChangeRecorder implements WorkingTreeModifiedListener { |
||||||
|
|
||||||
|
public static final String[] EMPTY = new String[0]; |
||||||
|
|
||||||
|
private Set<String> modified = new HashSet<>(); |
||||||
|
|
||||||
|
private Set<String> deleted = new HashSet<>(); |
||||||
|
|
||||||
|
private int eventCount; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onWorkingTreeModified(WorkingTreeModifiedEvent event) { |
||||||
|
eventCount++; |
||||||
|
modified.removeAll(event.getDeleted()); |
||||||
|
deleted.removeAll(event.getModified()); |
||||||
|
modified.addAll(event.getModified()); |
||||||
|
deleted.addAll(event.getDeleted()); |
||||||
|
} |
||||||
|
|
||||||
|
private String[] getModified() { |
||||||
|
return modified.toArray(new String[modified.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
private String[] getDeleted() { |
||||||
|
return deleted.toArray(new String[deleted.size()]); |
||||||
|
} |
||||||
|
|
||||||
|
private void reset() { |
||||||
|
eventCount = 0; |
||||||
|
modified.clear(); |
||||||
|
deleted.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
public void assertNoEvent() { |
||||||
|
assertEquals("Unexpected WorkingTreeModifiedEvent ", 0, eventCount); |
||||||
|
} |
||||||
|
|
||||||
|
public void assertEvent(String[] expectedModified, |
||||||
|
String[] expectedDeleted) { |
||||||
|
String[] actuallyModified = getModified(); |
||||||
|
String[] actuallyDeleted = getDeleted(); |
||||||
|
Arrays.sort(actuallyModified); |
||||||
|
Arrays.sort(expectedModified); |
||||||
|
Arrays.sort(actuallyDeleted); |
||||||
|
Arrays.sort(expectedDeleted); |
||||||
|
assertArrayEquals("Unexpected modifications reported", expectedModified, |
||||||
|
actuallyModified); |
||||||
|
assertArrayEquals("Unexpected deletions reported", expectedDeleted, |
||||||
|
actuallyDeleted); |
||||||
|
reset(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,129 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch> |
||||||
|
* and other copyright owners as documented in the project's IP log. |
||||||
|
* |
||||||
|
* This program and the accompanying materials are made available |
||||||
|
* under the terms of the Eclipse Distribution License v1.0 which |
||||||
|
* accompanies this distribution, is reproduced below, and is |
||||||
|
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||||
|
* |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or |
||||||
|
* without modification, are permitted provided that the following |
||||||
|
* conditions are met: |
||||||
|
* |
||||||
|
* - Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* - Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following |
||||||
|
* disclaimer in the documentation and/or other materials provided |
||||||
|
* with the distribution. |
||||||
|
* |
||||||
|
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||||
|
* names of its contributors may be used to endorse or promote |
||||||
|
* products derived from this software without specific prior |
||||||
|
* written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
package org.eclipse.jgit.events; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Collection; |
||||||
|
|
||||||
|
import org.eclipse.jgit.annotations.NonNull; |
||||||
|
|
||||||
|
/** |
||||||
|
* A {@link RepositoryEvent} describing changes to the working tree. It is fired |
||||||
|
* whenever a {@link org.eclipse.jgit.dircache.DirCacheCheckout} modifies |
||||||
|
* (adds/deletes/updates) files in the working tree. |
||||||
|
* |
||||||
|
* @since 4.9 |
||||||
|
*/ |
||||||
|
public class WorkingTreeModifiedEvent |
||||||
|
extends RepositoryEvent<WorkingTreeModifiedListener> { |
||||||
|
|
||||||
|
private Collection<String> modified; |
||||||
|
|
||||||
|
private Collection<String> deleted; |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new {@link WorkingTreeModifiedEvent} with the given |
||||||
|
* collections. |
||||||
|
* |
||||||
|
* @param modified |
||||||
|
* repository-relative paths that were added or updated |
||||||
|
* @param deleted |
||||||
|
* repository-relative paths that were deleted |
||||||
|
*/ |
||||||
|
public WorkingTreeModifiedEvent(Collection<String> modified, |
||||||
|
Collection<String> deleted) { |
||||||
|
this.modified = modified; |
||||||
|
this.deleted = deleted; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Determines whether there are any changes recorded in this event. |
||||||
|
* |
||||||
|
* @return {@code true} if no files were modified or deleted, {@code false} |
||||||
|
* otherwise |
||||||
|
*/ |
||||||
|
public boolean isEmpty() { |
||||||
|
return (modified == null || modified.isEmpty()) |
||||||
|
&& (deleted == null || deleted.isEmpty()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves the {@link Collection} of repository-relative paths of files |
||||||
|
* that were modified (added or updated). |
||||||
|
* |
||||||
|
* @return the set |
||||||
|
*/ |
||||||
|
public @NonNull Collection<String> getModified() { |
||||||
|
Collection<String> result = modified; |
||||||
|
if (result == null) { |
||||||
|
result = Collections.emptyList(); |
||||||
|
modified = result; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Retrieves the {@link Collection} of repository-relative paths of files |
||||||
|
* that were deleted. |
||||||
|
* |
||||||
|
* @return the set |
||||||
|
*/ |
||||||
|
public @NonNull Collection<String> getDeleted() { |
||||||
|
Collection<String> result = deleted; |
||||||
|
if (result == null) { |
||||||
|
result = Collections.emptyList(); |
||||||
|
deleted = result; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class<WorkingTreeModifiedListener> getListenerType() { |
||||||
|
return WorkingTreeModifiedListener.class; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void dispatch(WorkingTreeModifiedListener listener) { |
||||||
|
listener.onWorkingTreeModified(this); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,61 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2017, Thomas Wolf <thomas.wolf@paranor.ch> |
||||||
|
* and other copyright owners as documented in the project's IP log. |
||||||
|
* |
||||||
|
* This program and the accompanying materials are made available |
||||||
|
* under the terms of the Eclipse Distribution License v1.0 which |
||||||
|
* accompanies this distribution, is reproduced below, and is |
||||||
|
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||||
|
* |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or |
||||||
|
* without modification, are permitted provided that the following |
||||||
|
* conditions are met: |
||||||
|
* |
||||||
|
* - Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* |
||||||
|
* - Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following |
||||||
|
* disclaimer in the documentation and/or other materials provided |
||||||
|
* with the distribution. |
||||||
|
* |
||||||
|
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||||
|
* names of its contributors may be used to endorse or promote |
||||||
|
* products derived from this software without specific prior |
||||||
|
* written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.eclipse.jgit.events; |
||||||
|
|
||||||
|
/** |
||||||
|
* Receives {@link WorkingTreeModifiedEvent}s, which are fired whenever a |
||||||
|
* {@link org.eclipse.jgit.dircache.DirCacheCheckout} modifies |
||||||
|
* (adds/deletes/updates) files in the working tree. |
||||||
|
* |
||||||
|
* @since 4.9 |
||||||
|
*/ |
||||||
|
public interface WorkingTreeModifiedListener extends RepositoryListener { |
||||||
|
|
||||||
|
/** |
||||||
|
* Respond to working tree modifications. |
||||||
|
* |
||||||
|
* @param event |
||||||
|
*/ |
||||||
|
void onWorkingTreeModified(WorkingTreeModifiedEvent event); |
||||||
|
} |
Loading…
Reference in new issue