SCV
The SCV is a tool that every terran player absolutely must use to have a stable and well-organized (code)base.
Seriously though...
This project was inspired by the Git lecture I made for this year's Ruby course at my university. It is also my course project.
The name SCV has two different meanings:
- It is
VCS
(Version Control System) in reverse - It is the name of a StarCraft unit (a worker) which can gather resources and can also build and repair stuff.
Overview
The goal is to create a working (you don't say) version control system in Ruby.
The project itself is split into two parts: VCSToolkit and SCV. VCSToolkit is a Ruby gem that is supposed to provide the platform and common tools, upon which a VCS tool can be built. This is where most of the common operations for such a tool are (being) implemented. SCV only implements some of VCSToolkit's interfaces, extends (minimally) its classes and provides a user-friendly command-line interface to its methods.
Features
scv init
Initializes an empty repository.
Actually creates a .scv
directory in the current folder and the default head
label (pointer to a nil
commit).
scv status
Shows the list of created, modified and deleted files since the last commit.
scv diff
Shows the actual differences between the files in the last commit and the working directory.
scv commit
Commits the current state of the working directory. All changed, new and deleted files are commited.
You can explicitly set the commit author on every commit using the --author
option or set it once with scv config author "Your Name <your@email.com>"
.
You can also set the date (--date
), set the commit message (-m
or --message
) or amend the last commit (--amend
). If the -m
flag is not set the default terminal editor will be opened (as in Git).
Example: scv commit --author "Georgy Angelov <test@test.test>"
scv history
or scv log
Lists all commits, in reverse-chronological order with their id, date, author and message.
scv restore <paths>...
Restores files to the state they were in the head
commit. paths
can be files or directories. New files will not be removed, only changed and deleted files are restored.
You can optionally specify the source commit with -s
or --source
by giving its object_id, a label name that references it or an object_id and a relative offset (for example head~3
).
scv branch new <branch_name>
or scv branch create <branch_name>
Creates a new branch based on the current branch head.
scv branch delete <branch_name>
or scv branch remove <branch_name>
Deletes the specified branch. The commits are not lost, only the label is deleted.
scv branch switch <branch_name>
Switches the current directory to the specified branch head. It works as follows:
- Detects the changes that should be made to switch from the current branch to the other
- If you have modified files that would have to be overrwriten (modified) fails with an error
- Keeps all of your new or modified files and only overwrites unmodified ones
- May restore any deleted files that are present in the other branch
- Switches the current branch to
branch_name
(the following commits will be on branchbranch_name
)
scv config
Lists all configuration properties and values. The output is similar to the output of the tree
tool, because the configuration options can be nested:
level_0
├─ level_1_one
│ ├─ level_2_one: value
│ └─ level_2_two: true
└─ level_1_two: value
This configuration is stored in .scv/config.yml
and is relative only to the current scv repository.
scv config <key>
Shows the current value of <key>
. A key of the form one.two.three
can be used to reference nested properties.
scv config <key> <value>
Sets the option key
to value
. As in the previous command, you can use the one.two.three
form to reference nested properties. If the key doesn't exist it is created.
scv server
Starts an HTTP server to serve as a remote. The server listens on 0.0.0.0 (all addresses) on port 4242.
So the remote's address is (for example) http://localhost:4242
.
scv remote add <name> <address>
Adds a remote repository. <address>
is the HTTP url to a server started with scv server
scv remote delete <name>
Removes a remote.
scv remote fetch <name> <remote branch> [<local branch>]
Fetches remote history. Does not merge automatically and fails if it cannot do a Fast-Forward.
scv remote pull <name> <remote branch> [<local branch>]
Fetches the remote history to a local branch with a name of <remote_name>~<remote_branch>
(for example origin~master
) and after that merges that branch to <local branch>
.
The changes of the merge are not committed.
scv remote push <name> <local branch> [<remote branch>]
Pushes local history to remote and updates the remote branch to point to the newest commit. Fails if it cannot do a Fast-Forward.
Try it!
SCV is on RubyGems by the name scvcs
, because, unfortunately, scv
was already taken.
gem install scvcs
scv help
.scv structure
.scv/
objects/
59/
59873e99cef61a60b3826e1cbb9d4b089ae78c2b.json
...
...
refs/
HEAD.json
master.json
...
blobs/
59/
59873e99cef61a60b3826e1cbb9d4b089ae78c2b
...
...
Each object in .scv/objects/
is stored in a directory with a name of the first two symbols of the object id.
The blob objects follow the same naming scheme as the regular ones, but they are just a copy of the original user files (not in json
format).
The refs are named objects (object.named? == true) and can be enumerated. Currently the only named objects are labels which are used as pointers to unnamed ones.
Other
Contributions are most welcome, but I doubt there will be any :)
If you are interested in learning more about this you can ask me on Twitter @stormbreakerbg.