-
-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Version Control #383
Comments
YES to that. What I find to be missing from (all?) novel writing software is an easy way to compare the current version of the manuscript with a prior version, side-by-side. With an easy way to navigate through the versions until you can see the visual diff you're looking for. I keep my textual documents in a local git repository mostly because I hate the feeling of suddenly realizing that a chapter has gone missing and not being able to find it again. But it's not easy to find the change given the commit comments are the main guidance. |
It has always been my intention to add this at some point. Personally, I keep all my projects in a local git repo, but it would be nice to have a way to quickly scroll through and look at various versions. Still, implementing this in a clean way may be tricky due to the main project file also containing settings. |
Just making some notes of how to potentially implement this. TechnicalThe technical implementation is fairly simple as most of the heavy lifting is done with git via
Ease of UseThis can be implemented in two fairly simple and intuitive dialogs. One for browsing file history of present and deleted files, and one for making checkpoints of the project and reviewing the record of past files that have been removed (two tabs). Checkpointing
Restoring Tracked Files
Deleted Files
ReferencesGit resetting and diff: https://stackoverflow.com/questions/215718/how-can-i-reset-or-revert-a-file-to-a-specific-revision |
All good. Let me throw the following at the wall: Consider the following use case: I've just realized that I've lost a scene that describes a mountain valley. I know which file used to contain it. I have no idea when I deleted that text. I know it was about four paragraphs long. I would recognize it at a glance. So I'd like to be able to zip through all of the commits (perhaps using ↑ and ↓ until my eye catches the four missing paragraphs. novelWriter can reduce friction by:
Does this stick to the wall? |
As long as you know which file it was, that feature would be covered by the diff view. The diff view would be for a single file, showing the entire history of checkpoints (commits). Searching, I don't know. I suppose an automated walk through the history could achieve that. Something to consider. |
I am new to Personally, I just want to see the data format to be more portable and human-readable so that I can more easily version control it manually, even if there is no Git integration into the application (to start with). For example, I would like to see:
There might be more than this, but these are the immediate things I'm seeing as roadblocks for my use case. |
Hi, and thanks for the comment and feedback. The project file structure isn't meant to be human readable. The file structure itself is version control friendly (and file sync friendly), but the filenames aren't. That is why integration is being considered. I'm also considering other ways to achieve file versioning. As for your two points. The However, I expect the main issue here is the filename itself, which is just the internal hash key of the file. The reason the file is saved this way is that it is much simpler to keep track of the files and where they belong in the project tree when the file names are static and unique. There is no need to consider file name collisions, and no need to rename the actual files when the user changes the document name. There are no plans to change the file structure to mirror the project structure at this time. There are two ways to identify files though:
Your second point is a bit more straightforward to answer. The project structure is stored in the
If you run novelWriter from command line with the |
I've spent some time thinking about this. Also, see discussion in Issue #259 which covers the folder structure and format. There is a possible compromise here. When novelWriter opens a project, all files in the contents folder are listed and processed. As long as the first 13 characters remain static and unique like now, I can in principle add the document title after this. The scan while opening will be able to recognise the file based on the first 13 characters, and just store the file system name in a map for the duration of the writing session. I don't particularly like this idea, but it is a possible solution. It may cause issues with git versioning too since git considers a file rename to actually be a new file (although the diff may present it otherwise in most cases), which may or may not break version history if the file has been changed a lot while also being renamed. Edit: I will also switch on indentation permanently on the JSON files (also when not in debug mode). The cost is a larger file size, and slightly slower load time for the index. But it isn't really a big deal as it all loads in milliseconds anyway. |
Ah, okay, I was going to mark the I'm not sure how the software works, but I was just looking at the data format in the filesystem. I tried manually changing the filenames so that they were alphanumerically ordered in the filesystem, and updated their first line contents and the XML, and it appears I could do this successfully:
but I couldn't use strings. Could the Alternatively (more ideally for me), I noticed all the files in I actually use Mercurial as a version control system because it tracks file renames in the commits. I'd prefer to be able to keep this, which is why I'm not too fussed about the integration of Git :) |
Possibly. The
The
Any 13 character hexadecimal string is acceptable to novelWriter, so it is technically possible to do this, although it bypasses all the internal functionality in novelWriter that creates and handles new documents and makes sure they are created in the correct place with the correct meta data set. These renamed files will be unknown to novelWriter and considered "orphaned". But when you launch the app, you will be able to move them around into your project tree and the app will try to set the correct meta data. Any file that isn't 13 hexadecimals plus the extension (You can have a look at the
The contents of the files are not loaded when the project is opened. All the information about a project, sans raw text, is stored in the Anyway, it seems to me you're trying to use novelWriter as an editor of a collection of markdown files. That is not at all what it is intended for. What you're wanting to do here basically defeats the entire purpose of novelWriter and why I wrote it in the first place. I used to write large documents and projects (like draft novels, my theses, etc) by doing exactly what you want here: create folders of numbered files. Either Various applications for writing text manage data files in mainly two ways. Either all the text is packed in a zip file, like Libre Office and Microsoft Office (they use multiple xml files in a zip archive) or they do what novelWriter does: keep the data in a data hierarchy in a folder. Scrivener does this, and so does several other similar writing tools. It is a fairly robust approach, which is why I made the same choice. |
The |
The other day I stumbled across the Diffuse GitHub repository. Diffuse can display the differences among N files at one time. It has only one missing feature, word wrap. There is also a Git entanglement. My question is, is there anything about this project - written in Python :-) that might benefit novelWriter? For example could the user launch Diffuse from within novelWriter and have its N files comparison pop up? My other question is: But for the missing word wrap feature I think I really like Diffuse. Do you suppose this is an easy addition? No pressure but for the lack of word wrap I think Diffuse is the cat's meow for comparing many versions of a chapter in one display. |
I'm leaning towards implementing versioning by simply keeping multiple copies of each novelWriter document in a I still haven't gotten around to starting this as I had a huge burst of effort on nW at the beginning of the year, and needed a break. But I also want the versioning for my own projects, so I want to start on it soon. I can even implement a stage 1 solution that will just be able to preview the older version of the document in the viewer next to the current version in the editor. Then the user can copy/paste over text if needed. It's a starting point anyway. |
Taking a break after a huge burst is smart. My big takeaway from Diffuse is the ability to display N versions along with their deltas at once. Current tools max out at three versions. The use case I envision is choosing a particular scene and asking novelWriter to display the last N versions with diffs highlighted. Possibly with an option to then scroll left and right when more than N versions are in the project. You'd scroll up and down when the scene won't fit vertically and all N versions would scroll in unison. As far as I know from researching this, Diffuse comes close but lacks the word wrap feature. It's a tool meant for developers with short lines of code, I guess. |
I've been working on the version tool on and off for a while now, and I'm starting to converge at a suitable solution that I hope is useful without being overly complicated. The features implemented so far are:
Further features to be added:
Implementation:
|
Scrivener (yes, the eternal scrivener) has a really simple solution for this. Instead of storing a full diff of the entire project, you can (at your leisure) make a snapshot of each individual document and attach a comment to each snapshot. This may result that, with one scene you don't have any snapshots of a previous state (because you didn't need to), while with the next you might have five. The advantage of this is that you can work on each document independently. Reverting a document to a previous state, needn't affect the entire project. Another option would be to store the snapshot information (comment, timestamp/file version) in a separate file from the main text. How are the snapshots stored? I don't know, but I guess the full document simply gets stored, possibly with compression (zip?) applied. This eliminates the need for a full blown revision control system, and makes things easier on the writer. A snapshot could, for example, simply be a zipped json file with the text, comment for the snapshot, and timestamp/version number. No need to make things more complicated then they need to be. The choice to zip the snapshots, could be a configuration option (some people have short scenes, others have extremely long scenes), another option is to implement a threshold (KB? word count? User configurable?) when compression happens. |
That is exactly what my attempted implementation did. I plan to give this a try again at some point. I bet Scrivener just creates a copy of the file and assign it a new UUID, and link it via meta data. For full snapshots, the backup feature already does it. Of course, keeping track of them is a bit trickier as there may be many versions. In any case, I plan to do something here, but I may wait until I've sorted out the project storage feature #977. Zipping isn't really a big point as these are just text files that take up next to no space. |
It may be worthwhile to set up git integration for novel projects via pygit2. Only basic support is needed for a version history, possibly just a single branch with a linear history.
The text was updated successfully, but these errors were encountered: