Working in Version Control

 

 

Working in Version Control


 

 

For system administration to keep files in sync with multiple systems of unknown status.

First example shows how to safely get a file from server A to Server B and to make sure you don't involve other unexpected changes.

The later examples discuss how you prepare patches for upstream projects. Some would like you to send an email

 

Administrative Workflow

 

I strongly prefer Mercurial (short: hg) for system administration. It is a lot easier and less quirky than git. It's not as friendly if you maintain a large OSS project accepting patches from 100s of users and merging foreign branches. But that's not what you're likely to do. Mercurial has all the features and protection you need to do "normal" distributed version control with the added bonus of a well-designed CLI.

Also, less typing.

Mercurial

 

Server A

hg pull
hg st
hg up
sed -i 's/Black/Red/' my/file
hg diff my/file
hg commit -m "We changed Black to Red for better Alertness"
hg st
hg push

You will only need to "hg add" a new file, similarly "hg rm" will delete an existing one. When moving something to a more structured location, "hg mv" is the tool of choice. In fact it only does a OS side move, hg rm and hg add. No magic there.

 

Server B

hg st
hg pull
hg st
hg up

First we check the current status, then pull in our remote changes. We check those are what we expected with a quick glance at the status. Other people might also have done changes and pushed them at the same time. Those changes could even be based of an older state of the file in question, and might conflict with what we had. If they really touched the file we handle, a hg diff will come to help.

If we wanna proceed a hg update will apply the changes to the system.

GIT

The most important thing for non-devs working in git is that "git add" has a different understanding of "add" than other tools. Git maintains an appending stack of changes you're preparing towards a commit. So a git add may add a file to this stack but it is also used to place your newest modification to a file onto this stack. So it is decoupled from the filesystem state. This is far more powerful but also means you need to keep an eye on git status to see if your modifications of existing files are prepared for a commit.

This decoupled state means you can play back and forth between branches and changes very easily (and get lost within). A important tool related to this is "git stash" with lets you temporarily move a un-"add"-ed or uncommited change out of the way.

If you use git stash even irregularly you need to make it a practice to not leave the office till you have checked that you have NOT forgotten something in that stash. Or it will first become a pile and then a problem.

 

Server A

git pull
sed -i 's/Black/Red/' my/file
git diff my/file
git add my/file
git commit -m "We changed Black to Red for better Alertness"
git status
git push

 

Server B

git status
git pull

 

Bringing files back

List all deleted files (that were committed as "deleted" using git rm or git mv)

git log --diff-filter=D --summary

Find the missing file in there and also the commit ID.

Bring the file back by checking it out from the revision that still had it.

Add a ~1 suffix to the commit ID and give the filename:

git checkout 701f0ff0ac72ef135e8d74f4abe8f7c08408cda3~1 index.html.100.2

In git status it'll be shown as a new file and staged for commit.

You can now work with it as needed, but you'll need to finalize the change with git.

Your options:

  • Commit the file
  • Change, add and commit the file
  • Delete the file (git rm)

If everything was lost, it actually gets easier, you should be able to bring the whole directory back using

git checkout .

The .git directory needs to still exist!

If it's also gone, you need to freshly clone from the "upstream".

That will be found in the file .git/config in the "origin" section.

 

 

 

 

Identifying changes

 

How to make use of git blame

 

Reverting past changes

 

Creating Patches

Fetch the Repository if you never had it before

git clone source-repo.git

Otherwise, cd to it and update it

cd source-repo
git checkout master
git pull

 

Set up a real Email contact

git config
git config

 

For Pull Requests on GitHub, Bitbucket

git branch mypatch
git checkout mypatch
sed -i 's/Black/Red/' my/file
git diff my/file
git add my/file
git commit -m "We changed Black to Red for better Alertness"
 

 

Submitting a Github Pull Request

Then you can either do a git clone of "your" repository or use the "clone in desktop" button.

The rest will happen on the shell.

 

$ cd git  
$ cd rudder\-tools/
$ git branch config_transfer_script
$ git checkout  config_transfer_script 
Switched to branch 'config_transfer_script'
$ cd scripts
$ scp dev-server:rudder_config_ex.py .
rudder_config_ex.py          
$ git status
On branch config_transfer_script
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    rudder_config_ex.py
$ git add rudder_config_ex.py 
$ git status
On branch config_transfer_script
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
    new file:   rudder_config_ex.py
$ git commit rudder_config_ex.py -m "New script for API sync of objects between a source and destinatio>
[config_transfer_script 5025f51] New script for API sync of objects between a source and destination rudder server
 1 file changed, 226 insertions(+)
 create mode 100755 scripts/rudder_config_ex.py
$ git status
On branch config_transfer_script
nothing to commit, working directory clean

 

Now it's time to upload, with the desktop program it is just a "publish", otherwise a git push. The key is that you're pushing back to your repository.

 

 

Now you'll be invited to give more info and submit your patch as a pull request that will be seen in the other project.

 

And here you see it right in the upstream project:

 

Creating git Patches for Email

git branch mypatch
git checkout mypatch
sed -i 's/Black/Red/' my/file
git diff my/file
git add my/file
git commit -m "We changed Black to Red for better Alertness"
git format patch something