Skip to main content
Article

Source Only on One Desktop: Recovering an Integration from a Local Branch

7 min read 62 views

An integration can run in production for months while its source sits on a single developer's laptop. The CAR file was built, deployed and tested, the API was published on API Manager and an application subscribed to it, and nobody noticed that the commits behind it were never pushed. The gap only shows when someone asks a question the running system cannot answer: which application calls this API, what does the sequence validate, who changed it last.

This guide walks through bringing such an integration back into the shared repository without dragging unrelated changes along with it. The commands are plain Git and work the same whether your team hosts its code on GitHub, GitLab or Azure DevOps.

The scenario

The integration receives events through an API gateway and publishes them to a cloud messaging service. It has been through the test environment and into production. The deployment steps, the CAR, the API definition and the subscription are all documented. The source is not in the team's integration repository.

It exists on one developer's machine, on a feature branch with a handful of local commits and no upstream. While the branch exists in only one place, three things are at risk:

  • Nobody else can review, rebuild or patch the integration without going through that one developer.
  • The repository history does not reflect what runs in production, which weakens any audit or change request that refers to it.
  • A lost, stolen or reinstalled laptop takes the only copy of the source with it, leaving the deployed CAR as the only record.

How the branch drifted

A local feature branch rarely stays clean for months. This one was cut from a master that has moved on considerably since, and it carries one commit that does not belong to this integration at all: a small property-ordering change to a different integration, which has since reached master by its own route.

Pushing the branch as it is would produce a pull request that:

  • is based on an outdated master, so the diff against current master shows noise;
  • contains a commit for another integration, duplicating a change already upstream.

The goal is a branch that sits on current master and contains only the files of this integration.

Rebasing onto current master

Make a safety copy first

A rebase rewrites commits. Before starting, keep a pointer to the original state so it can be restored with a single reset:

git fetch origin
git branch backup/my-integration feature/my-integration
git checkout feature/my-integration

See what is actually unpushed

git log --oneline origin/master..HEAD
git branch -vv

The first command lists the commits on the branch that master does not have. The second confirms the branch has no upstream, which is what "never pushed" looks like.

Rebase

git rebase origin/master

Rebase skips any commit whose change is already present upstream. Git compares each commit's patch with the commits on master, and where it finds an identical change it reports "skipped previously applied commit" and moves on. The stray commit for the other integration disappears this way. If that change had reached master in a different form, for example squashed together with other edits, Git would not recognise it and you would get a conflict to resolve by hand instead.

You may come across advice to add -X ours to avoid conflicts. Be careful with it. During a rebase the meaning of "ours" is inverted: "ours" is the branch you are rebasing onto (origin/master) and "theirs" is the commit being replayed from your feature branch. So -X ours resolves every conflicting hunk in favour of master, without telling you. On a branch that edits shared files, your own changes can vanish while the rebase reports success. On a branch that only adds files there is nothing to conflict, so the plain command above is the safer choice: if a conflict does appear, it is a signal worth reading.

Verifying the scope before pushing

A rebase that finishes is not proof that the branch contains what you think it does. Check four things before pushing.

The branch sits on current master

git merge-base HEAD origin/master
git rev-parse origin/master

Both commands must print the same commit hash.

The commit count

git log --oneline origin/master..HEAD

Every commit listed must belong to this integration, and the count must match what you expect to be there.

The file list stays inside one folder

git diff --stat origin/master...HEAD
git diff --name-only origin/master...HEAD | grep -v '^MyIntegration/'

The first shows how many files changed. The second must print nothing: any line it returns is a file outside the integration's folder that has no business in this pull request.

Additions only

git diff --name-status origin/master...HEAD | grep -v '^A'

Again, the expected output is empty. Every entry is an added file, which confirms the branch modifies nothing that already exists on master. For a brand-new integration this is the property that matters most: the merge cannot affect any other integration in the repository.

Confirming the source matches production

The checks above prove what the pull request contains. They do not prove that those files are what runs in production, and that was the reason for the exercise. Build the CAR from the rebased branch and compare it with the deployed one. A CAR is a zip archive, so you can unpack both and diff the artefact files:

mkdir -p /tmp/car-built /tmp/car-deployed
unzip -q MyIntegrationCompositeExporter/target/*.car -d /tmp/car-built
unzip -q deployed/MyIntegration.car -d /tmp/car-deployed
diff -r /tmp/car-built /tmp/car-deployed

The paths depend on your project layout. Ignore differences in build metadata such as timestamps; any difference in a sequence, API or endpoint definition means the local branch is not what was deployed, and that needs answering before the pull request goes up.

Pushing and opening the pull request

With the scope and content confirmed, the branch can go to the remote:

git push -u origin feature/my-integration

The -u flag sets the upstream, so later git status output reports the branch against its remote counterpart rather than as local-only. Open the pull request into master from your hosting platform. The diff the reviewer sees is exactly the added files verified above.

The safety copy still holds the original, pre-rebase history, which the push does not replace. Keep it until the pull request is merged, then remove it:

git branch -D backup/my-integration

The same gap on our own site

Source is not the only thing that can live in one place. In September we wrote four articles for this blog through the admin screens of a local copy of pinuno.com.gh. They looked finished: they rendered and they were in the database. But a deploy ships code, not database rows, so nothing in the repository carried them, and production had never heard of them. The only copy was on one developer machine, which is the same exposure as the integration above.

The fix had the same shape as the rebase: put the content where the shared process can see it. Each article is now seeded by a database migration that inserts it by its slug and skips any slug already present, so the same migration runs safely against the machine the articles were written on, against production, and against a database rebuilt from scratch. This post reached the site the same way.

DNS records can be in the same position. In July, before moving one of our domains to our own nameservers, we found four records that existed only at the old DNS host: two DKIM public keys and two mail-provider verification records. They had been missed by the comparison done for the move, because the old host refused zone transfers and the comparison had to guess which subdomain names to check. Once the old zone was deleted they would have been unrecoverable, and a DKIM public key cannot be regenerated without the private half held by the mail provider. We captured all four into version control before the cutover. The lesson is the one this post started with: anything that exists in only one place, outside the shared record, is one deletion away from gone.

Conclusion

Deploying an integration from a local branch is easy to do and easy to overlook, because the running system gives no sign that its source is missing. The recovery is a few commands. What makes it safe is the verification afterwards: the branch on current master, a file list confined to one folder, nothing existing modified, and a built artefact that matches production. The pull request is then something a reviewer can approve without having to trust that the rebase did the right thing.

Our WSO2 courses cover building, deploying and managing integrations like this one, taught by the practitioners who do this work for a living.

C

Chrystal Akyempon

Related Articles

Article Info

Type
Article
Category
Enterprise Integration
Published
07 Oct 2026
Reading time
7 min

Search

Put this into practice

Our structured courses take these topics from article to hands-on skill, taught by the practitioners who write them.

Browse Courses