Skip to content

Commit

Permalink
Formatting and small improvements, little bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneBachmann committed Jan 3, 2018
1 parent da875ab commit d805e54
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 25 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Subversion Offline Solution (SOS 1.1.1) #
# Subversion Offline Solution (SOS 1.1.2) #

[![Travis badge](https://travis-ci.org/ArneBachmann/sos.svg?branch=master)](https://travis-ci.org/ArneBachmann/sos)
[![Build status](https://ci.appveyor.com/api/projects/status/fe915rtx02buqe4r?svg=true)](https://ci.appveyor.com/project/ArneBachmann/sos)
[![Code coverage badge](https://coveralls.io/repos/github/ArneBachmann/sos/badge.svg?branch=master)](https://coveralls.io/github/ArneBachmann/sos?branch=master)
[![PyPI badge](https://img.shields.io/pypi/v/sos-vcs.svg)](https://badge.fury.io/py/sos-vcs)

- License: [MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/)
- [Documentation](http://sos-vcs.net) [Code Repository](https://github.com/ArneBachmann/sos)
- [Documentation](http://sos-vcs.net), [Code Repository](https://github.com/ArneBachmann/sos)
- [Buy a coffee](http://PayPal.Me/ArneBachmann/) for the developer to show your appreciation!

### List of Abbreviations and Definitions ###
Expand Down Expand Up @@ -76,7 +76,7 @@ SOS supports three different file handling models that you may use to your likin


## Comparison with Traditional VCSs ##
When completing SOS 1.0 I incidentally discovered an interesting article by ... that discusses central weaknesses in the design of VCSs, with a focus on Git. Many of these arguments I have intuitively felt to be true as well and were the reason for the development of SOS: mainly the reduction of barriers between the developer's typical workflow and the VCS, which is most often used as a structured tool for "type and save in increments", while advanced features of Git are just very difficult to remember and get done right.
While completing version 1.0 of SOS, I incidentally discovered an interesting [article by Gregory Szorc](https://gregoryszorc.com/blog/2017/12/11/high-level-problems-with-git-and-how-to-fix-them/) that discusses central weaknesses in the design of popular VCSs, with a focus on Git. Many of his arguments I have intuitively felt to be true as well and were the reason for the development of SOS: mainly the reduction of barriers between the developer's typical workflow and the VCS, which is most often used as a structured tool for "type and save in increments", while advanced features of Git are just very difficult to remember and get done right.

- While Git is basically a large key-value store with a thin access interface on top, SOS keeps a very clear (folder) structure of branches, revisions and files
- Compared to SVN SOS's file store is much simpler and doesn't require an integrated database
Expand Down Expand Up @@ -146,6 +146,7 @@ By means of the `sos config set <key> <value>` command, you can set these flags

## Hints and Tipps ##
- Too speed up going offline, use the `sos offline --plain` option: It may reduce the time for going offline by a larger factor (in tests on a small laptop with BTRFS it was 30 times faster due to avoiding Python having to compress all versioned file contents)
- When specifying file patterns including glob markers on the command line, make sure you quote them correctly. On linux (bash, sh, zsh), put your patterns into quote (`"`), otherwise the shell will replace file patterns by any matching filenames instead of forwarding the pattern literally to SOS
- Many commands can be shortened to three, two or even one initial letters
- It might in some cases be a good idea to go offline one folder higher up in the file tree than your base working folder to care for potential deletions or renames
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os, shutil, subprocess, sys, time, unittest
from setuptools import setup, find_packages

RELEASE = "1.1.1"
RELEASE = "1.1.2"

print("sys.argv is %r" % sys.argv)
readmeFile = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'README.md')
Expand Down
42 changes: 23 additions & 19 deletions sos/sos.coco
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,29 @@ Usage: {cmd} <command> [<argument>] [<option1>, ...] When operating in of
--picky Setup Git-style mode: users pick files for each operation
online Finish working offline

branch [<name>] [--last] [--stay] Create a new branch from current file tree and switch to it
branch [<name>] Create a new branch from current file tree and switch to it
--last Use last revision, not current file tree, but keep file tree unchanged
--stay Don't switch to new branch, continue on current one
switch [<branch>][/<revision>] [--meta] Continue work on another branch
switch [<branch>][/<revision>] Continue work on another branch
--meta Only switch file tracking patterns for current branch, don't update any files
update [<branch>][/<revision>] Integrate work from another branch TODO add many merge and conflict resolution options
update [<branch>][/<revision>] Integrate work from another branch TODO add many merge and conflict resolution options
destroy [<branch>] Remove (current) branch entirely

commit [<message>] [--tag] Create a new revision from current state file tree, with an optional commit message
commit [<message>] Create a new revision from current state file tree, with an optional commit message
--tag Converts commit message into a tag that can be used instead of numeric revisions
changes [<branch>][/<revision>] List changed paths vs. last or specified revision
diff [<branch>][/<revision>] [--from=branch/rev.] List changes in file tree (or `--from` specified revision) vs. last (or specified) revision
add [<file pattern>] Add a tracking pattern to current branch (file pattern)
mv [<oldpattern>] [<newPattern>] Rename, move, or move and rename tracked files according to tracked file patterns
--soft Don't move or rename files, only the tracking pattern
rm [<file pattern>] Remove a tracking pattern. Only useful after "offline --track" or "offline --picky"
diff [<branch>][/<revision>] List changes in file tree (or `--from` specified revision) vs. last (or specified) revision
--from=branch/revision Take from revision as base to compare against (instead of current file tree)
add <file pattern> Add a tracking pattern to current branch (file pattern)
mv <oldpattern> <newPattern> Rename, move, or move and rename tracked files according to tracked file patterns
--soft Don't move or rename files, only the tracking pattern
rm <file pattern> Remove a tracking pattern. Only useful after "offline --track" or "offline --picky"

ls [<folder path>] [--patterns] List file tree and mark changes and tracking status
status List branches and display repository status
log [--changes] List commits of current branch
config [set/unset/show/add/rm] [<param> [<value>]] Configure user-global defaults.
log List commits of current branch
--changes Also list file differences
config [set/unset/show/add/rm] [<param> [<value>]] Configure user-global defaults.
Flags (1/0, on/off, true/false, yes/no):
strict, track, picky, compress
Lists (semicolon-separated when set; single values for add/rm):
Expand All @@ -84,13 +87,13 @@ Usage: {cmd} <command> [<argument>] [<option1>, ...] When operating in of
help, --help Show this usage information

Arguments:
<branch/revision> Revision string. Branch is optional and may be a label or index
Revision is an optional integer and may be negative to reference from the latest commits (-1 is most recent revision)
<branch>/<revision> Revision string. Branch is optional (defaulting to current branch) and may be label or number
Revision is an optional integer and may be negative to reference from the latest commits (-1 is most recent revision), or a tag

Common options:
--force Executes potentially harmful operations
--force Executes potentially harmful operations. SOS will tell you, when it needs you to confirm an operation with "--force"
for offline: ignore being already offline, start from scratch (same as 'sos online --force && sos offline')
for online: ignore uncommitted branches
for online: ignore uncommitted branches, just go online and remove existing offline repository
for commit, switch, update, add: ignore uncommitted changes before executing command
--strict Always perform full content comparison, don't rely only on file size and timestamp
for offline command: memorize strict mode setting in repository
Expand Down Expand Up @@ -395,7 +398,7 @@ class Metadata:
except: pass
if pinfo.size == 0:
with open(target, "wb"): pass
try: os.utime(target, (-1, pinfo.mtime / 1000.)) # update access/modification timestamps on file system
try: os.utime(target, (pinfo.mtime / 1000., pinfo.mtime / 1000.)) # update access/modification timestamps on file system
except Exception as E: error("Cannot update file's timestamp after restoration '%r'" % E)
return None
revision, source = _.findRevision(branch, revision, pinfo.nameHash)
Expand All @@ -405,7 +408,7 @@ class Metadata:
buffer = fd.read(bufSize)
to.write(buffer)
if len(buffer) < bufSize: break
try: os.utime(target, (-1, pinfo.mtime / 1000.)) # update access/modification timestamps on file system
try: os.utime(target, (pinfo.mtime / 1000., pinfo.mtime / 1000.)) # update access/modification timestamps on file system
except Exception as E: error("Cannot update file's timestamp after restoration '%r'" % E)
None

Expand Down Expand Up @@ -790,8 +793,9 @@ def config(argument:str, options:List[str] = []) -> None:
if options[0] not in c.keys(): Exit("Unknown key specified: %r" % options[0])
if options[1] not in c[options[0]]: Exit("Unknown value: %r" % options[1])
c[options[0]].remove(options[1])
else: # Show
for k, v in sorted(c.items()): print("%s => %r" % (k, v))
else: # Show or list
for k, v in sorted(c.items()): print("%s: %r" % (k.rjust(20), v))
if len(c.keys()) == 0: info("No configuration stored, using only defaults.") # TODO list defaults instead? Or display [DEFAULT] for each item above if unmodified
return
f, g = saveConfig(c)
if f is None: error("Error saving user configuration: %r" % g)
Expand Down
2 changes: 1 addition & 1 deletion sos/tests.coco
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ class Tests(unittest.TestCase):
sos.config("add", ["ignores", "ign2"]) # additional ignore pattern
sos.config("set", ["ignoresWhitelist", "ign1;ign2"]) # define a list of ignore patterns
out = wrapChannels(() -> sos.config("show")).replace("\r", "")
_.assertIn("ignores => ['ign1', 'ign2']", out)
_.assertIn(" ignores: ['ign1', 'ign2']", out)
out = sos.safeSplit(wrapChannels(() -> sos.ls()).replace("\r", ""), "\n")
_.assertInAny('... file1', out)
_.assertInAny('... ign1', out)
Expand Down
2 changes: 1 addition & 1 deletion sos/utility.coco
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def eoldet(file:bytes) -> bytes? =
if cr > lf: return b"\r" # older 8-bit machines
None # no new line contained, cannot determine

def Exit(message:str = "") -> None: print("[EXIT] " + message + ".", file = sys.stderr) if str != "" else None; sys.exit(1)
def Exit(message:str = "") -> None: print("[EXIT]" + (" " + message + "." if message != "" else ""), file = sys.stderr); sys.exit(1)

def user_input(msg:str) -> str = input(msg) # referenceso __builtin__.raw_input on Python 2

Expand Down

0 comments on commit d805e54

Please sign in to comment.