JGit merge - чтение содержимого конфликтующих файлов для слияния вручную во внешнем редакторе различий

Рассмотрим управление git-pull с помощью JGit следующим образом:

  1. используйте git-fetch и git-merge с setCommit=false (фиксация в тестовом режиме).
  2. если возникнут конфликты, прочитайте конфликтующие файлы и покажите их во внешнем редакторе слияния (скажем, kdiff3) для ручного слияния.
  3. продолжить слияние для неконфликтующих файлов (git-merge с setCommit=true)

Как я могу получить доступ к этим конфликтующим файлам (также известным как наши и их файлы) или, по крайней мере, получить доступ к их ObjectId?

вот иллюстрация

oFetchCommand.call()
...
MergeCommand oMergeCommand = m_oGit.merge();
oMergeCommand.setCommit(false); // dry run 
MergeResult oMergeResult = oMergeCommand.call();
if (oMergeResult.getConflicts() != null)
{
  // ?
  // TODO - read the complete 'our' and 'their' files, 
  // show them in an external editor for manual merge. 
}
...

Я предполагаю, что оптимальным решением будет получение ObjectId двух конфликтующих файлов.


person David B.    schedule 09.07.2015    source источник


Ответы (3)


Вы можете обрабатывать файл конфликта следующим образом:

Map allConflicts = oMergeResult.getConflicts();
for (String file : allConflicts.keySet()) {
    //Call to your external merge tool (this suppose 
    //kdiff3 is in your PATH)
    Runtime rt = Runtime.getRuntime();
    Process pr = rt.exec("kdiff3" + file + "-m");
}
person kad Dembele    schedule 09.07.2015
comment
есть ли способ получить ObjectId файлов?, если мне нужно отправить их на другой компонент дисплея - person David B.; 10.07.2015
comment
Вы можете получить идентификатор объекта объединенных коммитов (включая как конфликтующие, так и неконфликтующие файлы) с помощью ObjectID[] objectsId = oMergeResult.getMergedCommits();. Файлы конфликтов, возвращаемые с помощью String file=allConflicts.keySet(), также можно отправить куда угодно. - person kad Dembele; 10.07.2015

Чтобы получить доступ к содержимому файла в рамках определенной фиксации, вам необходимо разрешить и проанализировать интересующую вас фиксацию, затем использовать TreeWalk для получения идентификатора объекта содержимого файла и, наконец, использовать ObjectLoader для доступа к содержимому.

Например:

// Skip the next three lines if you have a fully parse RevCommit at hand
RevWalk revWalk = new RevWalk( repository );
RevCommit commit = revWalk.parseCommit( repository.resolve( commit-id ) );
revWalk.close();

String path = ... // repository-relative path to file
TreeWalk treeWalk = TreeWalk.forPath( repository, path, commit.getTree() );
ObjectId blodId = treeWalk.getObjectId( 0 ); // this is the objectId of the file
treeWalk.close();

ObjectLoader objectLoader = repository.open( blodId, Constants.OBJ_BLOB );
InputStream inputStream = objectLoader.openStream();
// use inputStream
inputStream.close();
person Rüdiger Herrmann    schedule 11.07.2015

git checkout-index --stage=all -- $path

выделяет три временных имени, содержащих три проиндексированных этапа (1 2 3, на основе наших).

git ls-files -us $path

перечисляет необъединенные пути и проиндексированные идентификаторы для этапов

person jthill    schedule 09.07.2015