Я могу ответить на две трети вашего вопроса здесь - почему возникает конфликт, и как выяснить, что происходит. Я не знаю интерфейса PyCharm, поэтому могу только догадываться, что он вам показывает.
Почему конфликт
В скриншоте, который вы показываете, причина конфликта заключается в том, что у вас есть коммит, который добавляет блок, смежный с блоком, который еще не существует потому что вы решили перебазировать его позже в последовательности: я думаю, что вы добавляете test...spatial()
после test...end()
, но последнее еще не существует. Я предполагаю, что это будет добавлено, когда коммит, который добавляет это, будет рассмотрен позже.
Когда Git видит непрерывные изменения, он не продвигается вперед, потому что для этого нужно угадывать, а это не всегда безопасно. Вы должны рассмотреть их и разрешить конфликт, чтобы сказать, каков правильный результат.
Как узнать, что происходит
Я воспроизвел ваш сценарий, добавив «line1» в конце файла a
в коммите, а затем добавив «line2» в второй коммит:
$ git log --format=oneline master
0a3b254 (master) line2
ef7e059 line1
Теперь я перезагружаюсь, чтобы отменить эти два коммита и получаю конфликт, когда выбираю 0a3b254
до ef7e059
, а команда командной строки сообщает мне, какой коммит имеет конфликт и останавливается там:
$ git rebase -i HEAD^^
Auto-merging a
CONFLICT (content): Merge conflict in a
error: could not apply 0a3b254... line2
Теперь вы используете другой интерфейс, поэтому я не знаю, показывает ли он фиксацию проблемы, но git status
сделает это, если вы запустите его в командной строке :
$ git status
interactive rebase in progress; onto bf27dcb
Last command done (1 command done):
pick 0a3b254 line2
Next command to do (1 remaining command):
pick ef7e059 line1
Теперь я могу проверить коммит, который я пытаюсь перебазировать с помощью git show 0a3b254
, и он показывает, что я добавляю «line2» после «line1».
Я также могу посмотреть на a
, чтобы увидеть, что это за конфликт:
$ cat a
asdf
<<<<<<< HEAD
=======
line1
line2
>>>>>>> 0a3b254... line2
Это говорит мне о том, что в master
здесь не было строк (между <<<<<<< HEAD
и =======
) и что в 0a3b254
у меня есть две строки. Я знаю, какие из них оставить, выполнив git show 0a3b254
, потому что в a
на данный момент ничего не говорится о том, что оставить.
Поэтому я разрешаю конфликт, оставив только «line2» из моей версии, и продолжаю ребазинг:
# edit a to keep just line2
git add a
git rebase --continue
...
CONFLICT (content): Merge conflict in a
error: could not apply ef7e059... line1
Опять я снова получаю конфликт с ef7e059, потому что два блока были добавлены в то же самое место, и Git, конечно, не будет знать, в каком порядке их размещать.
$ cat a
asdf
<<<<<<< HEAD
line2
=======
line1
>>>>>>> ef7e059... line1
Здесь Git сообщает мне, что я добавил line2 в предыдущем коммите на HEAD
и line1 в коммите, над которым я сейчас работаю, ef7e059. Это не помогает выяснить правильный порядок, также как и git show ef7e059
, но git show mybranch:a
показывает мне содержимое a
в исходной ветви (так как ветвь не обновляется, пока перебазирование не завершено) и помогает мне понять что мне нужно вставить строку 2 после строки 1.
# edit a to place its contents in the right order
git add a
git rebase --continue
Предположение о графическом интерфейсе PyCharm
В вашем интерфейсе я ожидаю, что Результат (центральная панель) - это место, где вы должны поместить результат разрешения конфликта, левая панель, вероятно, является состоянием кода в коммите, выбранном вишней, а правая панель, вероятно, является состоянием кода, в котором происходит выбор вишни.
На основании комментариев к этому ответу и информации о добавлении, которую вы показали в вопросе, я бы предположил, что Result содержит неправильную функцию, которую вам, возможно, придется заменить на ту, которую этот коммит фактически пытается добавить.
Нет ничего плохого в том, чтобы пытаться: вы всегда можете попробовать и посмотреть, работает ли он, и позже отменить перебазирование, если окончательные результаты не идентичны (согласно git diff
) коду перед перебазированием.
Определено в Prelude
,
type ShowS = String -> String
class Show a where
showsPrec :: Int -> a -> ShowS
show :: a -> String
showList :: [a] -> ShowS
type ReadS a = String -> [(a, String)]
class Read a where
readsPrec :: Int -> ReadS a
readList :: ReadS [a]
read :: (Read a) => String -> a
Короче это стандартные методы сериализации в Haskell. show :: (Show a) => a -> String
может превратить все, что является экземпляром Show
в строку, а read :: (Read a) = > String -> a
может превратить строку во все, что является экземпляром Read
(или сгенерировать исключение).
Большинство встроенных типов и структур данных в стандартной библиотеке иметь Показывать
и Читать
экземпляров; если вы составляете части из них, ваш тип также имеет экземпляры Show
и Read
.
type Table = [(String, String)]
load :: (Read a) => FilePath -> IO a
load f = do s <- readFile f
return (read s)
save :: (Show a) => a -> FilePath -> IO ()
save x f = writeFile f (show x)
Если Table
был типом данных,
The show
/read
approach will work fine, I use it as well, but only for small values. On larger, more complex values read
will be very slow.
This contrived example demonstrates the bad performance of read
:
data RevList a = (RevList a) :< a | Nil
deriving (Show, Read)
ghci> read "(((((((((((((((Nil)))))))))))))))" :: RevList Int
Also, read
won't be able to read some valid Haskell expressions, especially ones that use infix constructors (like the :<
in my example). The reason for this is that read
is unaware of the fixity of operators. This is also why show $ Nil :< 1 :< 2 :< 3
will generate a lot of seemingly redundant parentheses.
If you want to have serialization for bigger values, I'd suggest to use some other library like Data.Binary. This will be somewhat more complex than a simple show
, mainly because of the lack of deriving Binary
. However, there are various generic programming solutions to give you deriving
-like surrogates.
Conclusion: I'd say, use the show
/read
solution until you reach its limits (probably once you start building actual applications), then start looking at something more scalable (but also more complex) like Data.Binary.
Side note: To those interested in parsers and more advanced Haskell stuff; The examples I gave came from the paper: Haskel Do You Read Me?, on an alternative, fast read
-like function.
С вашей текущей функцией у вас есть проблема, когда строки в списке содержат «,» или «)», потому что это делает невозможным узнать, где заканчивается строка, когда вы пытаетесь прочитать данные снова. Вам нужно каким-то образом экранировать эти символы всякий раз, когда они появляются в строке.
Гораздо проще использовать show
и read
для преобразования ваших данных в строки и обратно в сделайте это самостоятельно:
save :: Table -> IO ()
save zs = writeFile "database.txt" (show zs)
show
экранирует специальные символы и проверяет, что данные имеют формат, который может быть проанализирован с помощью read
. Чтобы загрузить данные, вы должны прочитать файл в строку и передать его в , прочитать
, чтобы преобразовать его в желаемую структуру данных.