sapling/eden/fs/inodes/DiffContext.h

55 lines
1.6 KiB
C
Raw Normal View History

/*
* Copyright (c) 2004-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#pragma once
#include "eden/fs/model/git/GitIgnoreStack.h"
namespace facebook {
namespace eden {
class InodeDiffCallback;
class ObjectStore;
/**
* A small helper class to store parameters for a TreeInode::diff() operation.
*
* These are parameters that remain fixed across all subdirectories being
* diffed. This class is mostly just for convenience so that we do not have to
* pass these items in individually as separate parameters to each function
* being called.
*/
class DiffContext {
public:
augment JournalDelta with unclean paths on snapshot hash change Summary: We were previously generating a simple JournalDelta consisting of just the from/to snapshot hashes. This is great from a `!O(repo)` perspective when recording what changed but makes it difficult for clients downstream to reason about changes that are not tracked in source control. This diff adds a concept of `uncleanPaths` to the journal; these are paths that we think are/were different from the hashes in the journal entry. Since JournalDelta needs to be able to be merged I've opted for a simple list of the paths that have a differing status; I'm not including all of the various dirstate states for this because it is not obvious how to reconcile the state across successive snapshot change events. The `uncleanPaths` set is populated with an initial set of different paths as the first part of the checkout call (prior to changing the hash), and then is updated after the hash has changed to capture any additional differences. Care needs to be taken to avoid recursively attempting to grab the parents lock so I'm replicating just a little bit of the state management glue in the `performDiff` method. The Journal was not setting the from/to snapshot hashes when merging deltas. This manifested in the watchman integration tests; we'd see the null revision as the `from` and the `to` revision held the `from` revision(!). On the watchman side we need to ask source control to expand the list of files that changed when the from/to hashes are different; I've added code to handle this. This doesn't do anything smart in the case that the source control aware queries are in use. We'll look at that in a following diff as it isn't strictly eden specific. `watchman clock` was returning a basically empty clock unconditionally, which meant that most since queries would report everything since the start of time. This is most likely contributing to poor Buck performance, although I have not investigated the performance aspect of this. It manifested itself in the watchman integration tests. Reviewed By: simpkins Differential Revision: D5896494 fbshipit-source-id: a88be6448862781a1d8f5e15285ca07b4240593a
2017-10-17 08:22:18 +03:00
DiffContext(InodeDiffCallback* cb, bool listIgnored, ObjectStore* os)
: callback{cb}, store{os}, listIgnored{listIgnored} {
// TODO: Load the system-wide ignore settings and user-specific
// ignore settings into rootIgnore_.
}
const GitIgnoreStack* getToplevelIgnore() const {
return &rootIgnore_;
}
InodeDiffCallback* const callback;
ObjectStore* const store;
/**
* If listIgnored is true information about ignored files will be reported.
* If listIgnored is false then ignoredFile() will never be called on the
* callback. The diff operation may be faster with listIgnored=false, since
* it can completely omit processing ignored subdirectories.
*/
bool const listIgnored;
private:
GitIgnoreStack rootIgnore_{nullptr};
};
}
}