Fossil Forum

Demo: checking in files without a checkout
Login

Demo: checking in files without a checkout

Demo: checking in files without a checkout

(1) By Stephan Beal (stephan) on 2021-11-21 14:39:03 [link] [source]

This is ever-so-slightly off-topic because it's a libfossil demo, but only a tiny handful of people follow the libfossil goings-on and this might be interesting for some of you folks who aren't in that tiny handful...

Management summary: libfossil, as of a few moments ago, has an app which enables users to create checkins without having a checkout.

That might sound like an odd feature, but it has been requested a time or two over the years and it has some valid use cases, e.g. archiving log files via cron jobs.

What follows is a brief demo of f-ciwoco (CheckIn WithOut CheckOut), noting that (A) it's brand new (literally less than an hour old) and still subject to any number of usage changes and (B) we'll be using only libfossil tools for this demo, rather than fossil itself:

First, create a new repo (for demo purposes only):

[stephan@nuc:~/tmp]$ f-new ciwoco.f -m "Demo repo for f-ciwoco."
Created repository: ciwoco.f
server-code    = 909c30a6fdccb9e8d0914115ef732e39328450d0
project-code   = 37c0b3a2c5fbf9b8c80b0cc82f01d88542d0f6ef
hash-policy    = 2
admin-user     = stephan (password=fe3b43)

Try ciwoco in dry-run mode:

[stephan@nuc:~/tmp]$ f-ciwoco -R ciwoco.f /etc/hosts:foo/hosts /etc/sysctl.conf:bar/SystemCtrl.conf -m 'adding files' -V
Deriving from checkin trunk (RID 1)
Adding [/etc/hosts] as [foo/hosts]
Adding [/etc/sysctl.conf] as [bar/SystemCtrl.conf]
Calculating R-card... 
Dry-run mode. Rolling back.
C adding\sfiles
D 2021-11-21T14:15:35.203
F bar/SystemCtrl.conf 0fbf88bcd0515313cdd828cf4fb2bacd8f8e7cca91c642482c01c90c0d1868fd
F foo/hosts 5d60a594defe68796b2ac2f9c4b80bbb4e1eefcbe4ba3a3aee6d0f3dacf0233c
P bd8ef376457c4446fb887d8addcf8da57f75c86fb7c0a759b2ae4ebfb1b1a4c5
R 8cabf4f5baf9f538d3b401dcb918c7e3
U stephan
Z a7394a7d906eb07fab752cc56234daf1

Same thing, in "wet run" mode:

[stephan@nuc:~/tmp]$ f-ciwoco -R ciwoco.f /etc/hosts:foo/hosts /etc/sysctl.conf:bar/SystemCtrl.conf -m 'adding files' --wet-run
Deriving from checkin trunk (RID 1)
Saved checkin 9abb48ee809f6113fae6ca744bbbbae84f9e433f139a7665157bf1439a6e95e2 (RID 4)
ACHTUNG: current checkouts of this repo will not automatically know about this commit: they'll need to 'update' to see the changes.

Take a look at the timeline:

[stephan@nuc:~/tmp]$ f-timeline -f -R ciwoco.f 
checkin  [9abb48ee809f] @ 2021-11-21 15:15:45 by [stephan] branch [trunk]

	adding files

	Change     File UUID          Size Name
	ADDED      0fbf88bcd051       2424 bar/SystemCtrl.conf
	ADDED      5d60a594defe        281 foo/hosts

checkin  [bd8ef376457c] @ 2021-11-21 15:15:23 by [stephan] branch [trunk]

	Demo repo for f-ciwoco.

It can, of course, add new versions of existing files and will "deltify" them the same way fossil does.

The source code for the app demonstrates how easy it was to implement:

Now comes the harder part of refining it to do useful things like recognize the case where no changes were made, recursively add directories, strip a common prefix off of filenames (e.g. to check in /var/log/blah/* to blah/*), etc.

(2) By sean (jungleboogie) on 2021-11-21 19:54:55 in reply to 1 [link] [source]

Nice work, Stephan!

And now for something tangentially related…which may already have a solution.

I know of a few ways to get files from a repo without needing to clone the repo:

  1. Download the tarball of the trunk repo with a known url each time
  2. Navigate to the desired file on the UI and click download
  3. From the option above, bookmark the URI and use something like curl to get the trunk version of the file each and every time.
  4. Use your (Stephan) mini download script, but you would need to know which files to include beforehand.

So as an example, I want the trunk copy foo/hosts downloaded without needing to copy a URI or clone the repo.

Then I suppose edits could be made to that file and checked back in with your latest enhancement.

(3) By anonymous on 2021-11-21 23:19:56 in reply to 2 [link] [source]

Another way to download individual files without cloning the entire repo:

  1. Access the /raw/tip or another branch.

  2. (Optional) Verify if the deck is valid.

  3. Find the F cards of the files that you want to do. (If it is a delta manifest then you might also need to look at the base manifest.)

  4. Access the /raw/ with the hash of the file that you want to download.

  5. (Optional) Verify the hash of the file.

Note that if you want to commit a check-in and do not have all of the files, then you will have to omit the R card.

(4) By Stephan Beal (stephan) on 2021-11-22 01:24:11 in reply to 3 [link] [source]

Note that if you want to commit a check-in and do not have all of the files, then you will have to omit the R card.

Interestingly, that's not the case: libfossil calculates the R-card based on the db-side data, not checked-out files. That allows us to calculate the R-card even when checking in just a subset of files this way. This new tools adds an R-card by default but can be told not to.

(5) By anonymous on 2021-11-22 02:09:19 in reply to 4 [link] [source]

If you have the repository database, then yes, you can calculate the R card in this way. However, I was replying to the message about if you will get files from a repo without needing to clone the repo, then you might not have all of the data of all of the files.

(6.1) By sean (jungleboogie) on 2021-11-22 02:54:19 edited from 6.0 in reply to 3 [source]

Right, but it looks like this involves using the UI to get that info as well.

My ideas more like:

f-cwor foo/hosts

cor being copy without repo.

As an example, https://raw.githubusercontent.com/sqlite/sqlite/master/ext/misc/csv.c

Going to that URI today will give me the latest version; going to that URI six weeks from now will give me the latest version at that time. Both versions of the file may end up being the same or they could be different.

Edit…

At any rate, I didn’t mean to hijack Stephan’s post on what he’s done with libfossil. Great job, Stephan and thanks for continuing on with it.

(7) By Stephan Beal (stephan) on 2021-11-22 03:25:26 in reply to 6.1 [link] [source]

f-cwor foo/hosts

That actually would be easy to implement so long as the tool always extracts the files using the full paths (with no option for translating the names during extraction). Something like...

$ f-extract -R repo.f -r trunk a/b/c.txt d/e/f.c
# might write under the current dir:
a/b/c.txt
d/e/f.c

$ f-extract --dest-dir /blah ...
# would place them under /blah, etc.

$ f-extract --glob 'a/*' ...

etc.

One of my favorite parts of the libf API is its use of a "for-each" API for extracting the content of a given repo version. This allows client code to simply pass a callback function which gets passed the state of each file in the given checkin. In pseudocode, something like:

fossilRepoForEach("trunk", function(file){
    saveBlob(file.name, file.content);
});

That capability is the basis of f-zip and the open and checkout operations.

Consider f-extract to be on my near-term TODO list.

(8) By Stephan Beal (stephan) on 2021-11-22 05:22:02 in reply to 7 [link] [source]

Consider f-extract to be on my near-term TODO list.

$ ./f-extract -R repo.f auto.def -g '*.md' -d /tmp/x
./f-extract: ERROR #108 (FSL_RC_ALREADY_EXISTS): File already exists and --overwrite flag not specified: /tmp/x/LICENSES/README.md

$ ./f-extract -R repo.f auto.def -g '*.md' -d /tmp/x --overwrite

$ ./f-extract -R repo.f auto.def -g '*.md' -d /tmp/x --overwrite -V
/tmp/x/LICENSES/README.md
/tmp/x/auto.def
/tmp/x/doc/db-udf.md
/tmp/x/f-apps/index.md

# Before extracting anything, it confirms that all
# arguments refer to files:

$ ./f-extract no-such-file nope auto.def -g '*.md' -d /tmp/x -w -V -n
Error: not found in repository:
    no-such-file
    nope
./f-extract cli.c:934: ERROR #107 (FSL_RC_NOT_FOUND): 2 files not found in repository.

It accepts its list of files as filename arguments (must be exact matches) or as one or more -g/--glob flags, each of which may be a comma-separated list of globs (same format as fossil's glob lists).

This isn't yet checked in but will be soon.