Saturday, September 30, 2017

Day-to-day use of the Pure Git with Convention over Git

This page explains how to use the Pure Git with Convention over Git solution to synchronize Git remote repositories.
Or how to live with Git remote repositories auto synchronized by it.

But consider to use git-sinc, the next generation of remote Git repositories synchronization.

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.
There is an auto conflict resolving that deletes 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 = CoG

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

Naming convention

Convention over Git uses any naming convention that allows to define owners of each Git-branch.

As an example the prefixed names.
Each remote Git repository owns its prefix and all non-fast-forward conflicts will be solved in favor of a prefix owner.
company1/develop vs company2-develop
company1/JIRA-123 vs company2-JIRA-321

So, a naming convention in Git can be any conventional separation of names

  • Some defined prefixes or suffixes on both repositories.
  • A slave repository can have a prefix and a master repository have nothing. I.e. all non conventional (non-prefixed) branches belongs to the master Git-repository
  • etc

Conventions over Git gives many advantages and drastically simplifies any implementation.
Possibly it is unclear at first glance, but it's worth it.

  • Please, do not migrate everything between repositories. It is absolutely not necessary and even harmful! CoG just allows to save your repositories in sanity.
  • GoG adds some level of self responsibility and implies some self management. You shouldn't control everything. Believe in your teams.
Ohh, lost my thoughts here. Possibly I'll continue later.

Thursday, September 28, 2017

Cheat-sheet of implementation for Pure Git with Convention over Git

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

(Consider to use git-sinc, the next generation of remote Git repositories synchronization.)

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 and on the project's home page.

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  a1/*  b2/*
git ls-remote --heads  a1/*  b2/*

Updating repositories of synchronization-agent. (the first)

# for a1 sync-repo
git fetch --prune  +heads/a1/*:heads/a1/*  +heads/b2/*:heads/b2/*
# for b2 sync-repo
git fetch --prune  +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  heads/a1/*:heads/a1/*
# from b2 sync-repo
git push --prune  heads/b2/*:heads/b2/*

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

Plain syncing of refs

# from a1 sync-repo
git push  heads/a1/*:heads/a1/*  heads/b2/*:heads/b2/*
# from b2 sync-repo
git push  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  +heads/a1/*:heads/a1/*
# from b2 sync-repo
git push  +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.