Saturday, September 30, 2017

Day-to-day use of Convention over Git

This page explains how to use the Conventions over Git on a daily basis.
Or how to live with Git remote repositories auto synchronized by the Convention over Git.

How to work with the Convention over Git

Use Git, as you always do, except for the following.
  • Name branches and tags with a prefix of your side (as an example "company/some_branch_name").
  • Do plain commits to prefixed branches of your side.
  • Delete only branches and tags of your side. Deleted by you refs from other sides will be recreated automatically.

How to migrate your work to another side refs

All refs will be updated on all sides automatically.
But when you will want to migrate your work to another side, you will do one of the following.
By a merge or cherry-pick from your side
  1. Do a plain merge from you prefixed branch to a prefixed branch of another side.
  2. After a synchronization interval do "git fetch" and check your merge-commit is still there.
  3. If not, then just repeat everything.
This is not a problem, really. Your local Git repository always preserves all local branches (it even stores deleted commits in the Git's reflog).

Commits between different sides may disappear if somebody else do a "git push" to the same branch before you.
The auto conflict resolving of Convention over Git will delete your merge-commit only in a case of non-fast-forward differences. This is not so often.

By a merge or cherry-pick at another side.
Nobody doing so :-)
This works if your can connect to a remote Git repository of the other side.
Wait the sin—Āhronization interval and your commits will appear on the remote repository of the other side.
Do a merge between branches there.
Now this is safe. No checks, no worries. Done.

By a plain commit on your side to an other side ref.
Junior developers doing so. Prevent this.
If you feel lucky you can do a plain commit directly to a branch of the other side.
Again, you must recheck you commit is still there after a synchronization interval.
And if you're unlucky then you'll end up searching your commit in the Git-reflog. It is time wasting operation. I warned you.
So, be careful or inform guys on the other side.

Out of convention refs

In the provided implementation mode of the Convention over Git, the sides only see conventional (prefixed) refs.
Not-prefixed branches and tags will stay undisclosed for other sides. They even can have the same names on different remote Git repositories.

Convention over Git

Convention over Git allows automated conflict solving during automated synchronization of remote Git repositories.

Naming convention
It is any prefixed name. Each remote Git repository owns its prefix and non-fast-forward conflicts for prefixed Git refs will be solved in favor of an owner.
Examples
company1/develop, company2/develop
company1/JIRA-123, company2/JIRA-321


Thursday, September 28, 2017

Cheat-sheet of implementation for Convention over Git

This is a cheat-sheet for the simplest implementation of the Convention over Git.
It is used for an automated synchronization between remote Git repositories.

If you understand the idea of the Convention over Git, then it is easier to look at this cheat-sheet. Otherwise look at the Convention over Git article.

Here we'll start.
Let's say some two development teams in companies "A-1" and "B-2" want to auto-synchronize a Git-repository named "repo" with each other.

We have some preconditions:
  • The teams want to synchronize only conventionally named branches. Not the entire repository, which is also possible.
  • GitLab of one of the teams automatically blocks tags deletion. So, they decided to exclude Git-tags from syncing.
  • Guys have no time for optimization and struggle with GitLab, they just want a working solution.
  • Logic below uses bare repositories (sync-repo) hosted on some your synchronization-agent machine.
  • They have a side effect "do not push to another side branch more than once a minute".

In every synchronization cycle we shall do:


Creating a bare repositories of a synchronization-agent, if they do not exist. One for each side (team).


Checking if there are changes in remote Git repositories. Interrupt if not.

git ls-remote --heads  https://git.a1.com/repo  a1/*  b2/*
git ls-remote --heads  https://b2.com/git/repo  a1/*  b2/*


Updating repositories of synchronization-agent. (the first)

# for a1 sync-repo
git fetch --prune https://git.a1.com/repo  +heads/a1/*:heads/a1/*  +heads/b2/*:heads/b2/*
# for b2 sync-repo
git fetch --prune https://b2.com/git/repo  +heads/a1/*:heads/a1/*  +heads/b2/*:heads/b2/*


Checking if the Deletion & Recovering is allowable. Use git show-ref and git show to do this.

Each repository at least must have a branch with the same sha-1 and also some fixed commit.
Scip Deletion & Recovering if there are no differences in current ref-names (without sha-1).


Deletion & Recovering of refs (also a partial fast-forward synchronization as a side effect).

# from a1 sync-repo
git push --prune https://b2.com/git/repo  heads/a1/*:heads/a1/*
# from b2 sync-repo
git push --prune https://git.a1.com/repo  heads/b2/*:heads/b2/*


Updating repositories of synchronization-agent. (repeat of the first)


Plain syncing of refs

# from a1 sync-repo
git push https://b2.com/git/repo  heads/a1/*:heads/a1/*  heads/b2/*:heads/b2/*
# from b2 sync-repo
git push https://git.a1.com/repo  heads/a1/*:heads/a1/*  heads/b2/*:heads/b2/*


Updating repositories of synchronization-agent. (repeat of the first)


Resolving conflicts of conventionally named refs. Do non-fast-forward pushes.

# from a1 sync-repo
git push https://b2.com/git/repo  +heads/a1/*:heads/a1/*
# from b2 sync-repo
git push https://git.a1.com/repo  +heads/b2/*:heads/b2/*

All-in-one working implementation

You can test an all-in-one implementation in a project that have I published on GitHub.
It creates local and remote repositories in the project folder, so you can easily emulate and play with Convention over Git on your own.