Skip to content

Commit

Permalink
Add branch/merge section to Snowflake tutorial.
Browse files Browse the repository at this point in the history
  • Loading branch information
theory committed Jul 27, 2018
1 parent 5f056ea commit 1f9b7a5
Show file tree
Hide file tree
Showing 8 changed files with 308 additions and 7 deletions.
3 changes: 2 additions & 1 deletion lib/sqitchtutorial-exasol.pod
Original file line number Diff line number Diff line change
Expand Up @@ -941,12 +941,13 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Make sure we can
Note the use of C<--show-tags> to show all the deployed tags. Make sure we can
revert, too:

> sqitch rebase -y --onto @HEAD^
Reverting changes to userflips @v1.0.0-dev1 from flipr_test
- hashtags .. ok
> sqitch deploy
Deploying changes to flipr_test
+ hashtags .. ok

Expand Down
2 changes: 1 addition & 1 deletion lib/sqitchtutorial-firebird.pod
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Now make it so:
Note the use of C<--show-tags> to show all the deployed tags. Now make it so:

> rm -rf flipr-v1.0.0-dev1*
> git add .
Expand Down
2 changes: 1 addition & 1 deletion lib/sqitchtutorial-mysql.pod
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,7 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Now make it so:
Note the use of C<--show-tags> to show all the deployed tags. Now make it so:

> git add .
> git commit -am 'Add flips table.'
Expand Down
2 changes: 1 addition & 1 deletion lib/sqitchtutorial-oracle.pod
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Now make it so:
Note the use of C<--show-tags> to show all the deployed tags. Now make it so:

> git add .
> git commit -am 'Add flips table.'
Expand Down
299 changes: 299 additions & 0 deletions lib/sqitchtutorial-snowflake.pod
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,305 @@ Now, package it up and ship it!
> mv bundle flipr-v1.0.0-dev1
> tar -czf flipr-v1.0.0-dev1.tgz flipr-v1.0.0-dev1

=head1 Making a Hash of Things

Now that we've got the basics of the app done, let's add a feature. Gotta
track the hashtags associated with flips, right? Let's add a table for them.
But since other folks are working on other tasks in the repository, we'll work
on a branch, so we can all stay out of each other's way. So let's branch:

> git checkout -b hashtags
Switched to a new branch 'hashtags'

Now we can add a new change to create a table for hashtags.

> sqitch add hashtags --requires flips -n 'Adds table for storing hashtags.'
Created deploy/hashtags.sql
Created revert/hashtags.sql
Created verify/hashtags.sql
Added "hashtags [appschema flips]" to sqitch.plan

You know the drill by now. Add this to F<deploy/hashtags.sql>

CREATE TABLE flipr.hashtags (
flip_id INTEGER NOT NULL REFERENCES flipr.flips(id),
hashtag VARCHAR(128) NOT NULL,
PRIMARY KEY (flip_id, hashtag)
);

Again, select from the table in F<verify/hashtags.sql>:

SELECT flip_id, hashtag FROM flipr.hashtags WHERE FALSE;

And drop it in F<revert/hashtags.sql>

DROP TABLE flipr.hashtags;

And give it a whirl:

> sqitch deploy
Deploying changes to flipr_test
+ hashtags .. ok

Look good?

> sqitch status --show-tags
# On database flipr_test
# Project: flipr
# Change: d750cbeec487841c45715115a31297739fbb4046
# Name: hashtags
# Deployed: 2018-07-27 11:53:02 -0400
# By: Marge N. O’Vera <marge@example.com>
#
# Tag:
# @v1.0.0-dev1 - 2018-07-27 11:41:13 -0400 - Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)

Note the use of C<--show-tags> to show all the deployed tags. Make sure we can
revert, too:

> sqitch revert -y --onto @HEAD^
Reverting changes to userflips @v1.0.0-dev1 from flipr_test
- hashtags .. ok
> sqitch deploy
Deploying changes to flipr_test
+ hashtags .. ok

Great! Now make it so:

> git add .
> git commit -m 'Add hashtags table.'
[hashtags 06a0bf4] Add hashtags table.
4 files changed, 19 insertions(+)
create mode 100644 deploy/hashtags.sql
create mode 100644 revert/hashtags.sql
create mode 100644 verify/hashtags.sql

Good, we've finished this feature. Time to merge back into C<master>.

=head2 Emergency

Let's do it:

> git checkout master
Switched to branch 'master'
> git pull
Updating 84ed9db..31d026c
Fast-forward
deploy/lists.sql | 11 +++++++++++
revert/lists.sql | 4 ++++
sqitch.plan | 2 ++
verify/lists.sql | 6 ++++++
4 files changed, 23 insertions(+)
create mode 100644 deploy/lists.sql
create mode 100644 revert/lists.sql
create mode 100644 verify/lists.sql

Hrm, that's interesting. Looks like someone made some changes to C<master>.
They added list support. Well, let's see what happens when we merge our
changes.

> git merge --no-ff hashtags
Auto-merging sqitch.plan
CONFLICT (content): Merge conflict in sqitch.plan
Automatic merge failed; fix conflicts and then commit the result.

Oh, a conflict in F<sqitch.plan>. Not too surprising, since both the merged
C<lists> branch and our C<hashtags> branch added changes to the plan. Let's
try a different approach.

The truth is, we got lazy. Those changes when we pulled master from the origin
should have raised a red flag. It's considered a bad practice not to look at
what's changed in C<master> before merging in a branch. What one I<should> do
is either:

=over

=item *

Rebase the F<hashtags> branch from master before merging. This "rewinds" the
branch changes, pulls from C<master>, and then replays the changes back on top
of the pulled changes.

=item *

Create a patch and apply I<that> to master. This is the sort of thing you
might have to do if you're sending changes to another user, especially if the
VCS is not Git.

=back

So let's restore things to how they were at master:

> git reset --hard HEAD
HEAD is now at 31d026c Merge branch 'lists'

That throws out our botched merge. Now let's go back to our branch and rebase
it on C<master>:

> git checkout hashtags
Switched to branch 'hashtags'
> git rebase master
First, rewinding head to replay your work on top of it...
Applying: Add hashtags table.
Using index info to reconstruct a base tree...
M sqitch.plan
Falling back to patching base and 3-way merge...
Auto-merging sqitch.plan
CONFLICT (content): Merge conflict in sqitch.plan
error: Failed to merge in the changes.
Patch failed at 0001 Add hashtags table.
Use 'git am --show-current-patch' to see the failed patch

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

Oy, that's kind of a pain. It seems like no matter what we do, we'll need to
resolve conflicts in that file. Except in Git. Fortunately for us, we can tell
Git to resolve conflicts in F<sqitch.plan> differently. Because we only ever
append lines to the file, we can have it use the "union" merge driver, which,
according to
L<its docs|http://git-scm.com/docs/gitattributes#_built-in_merge_drivers>:

=over

Run 3-way file level merge for text files, but take lines from both versions,
instead of leaving conflict markers. This tends to leave the added lines in
the resulting file in random order and the user should verify the result. Do
not use this if you do not understand the implications.

=back

This has the effect of appending lines from all the merging files, which is
exactly what we need. So let's give it a try. First, back out the botched
rebase:

> git rebase --abort
HEAD is now at 06a0bf4 Add hashtags table.

Now add the union merge driver to F<.gitattributes> for F<sqitch.plan>
and rebase again:

> echo sqitch.plan merge=union > .gitattributes
> git rebase master
First, rewinding head to replay your work on top of it...
Applying: Add hashtags table.
Using index info to reconstruct a base tree...
M sqitch.plan
Falling back to patching base and 3-way merge...
Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

> cat sqitch.plan
%syntax-version=1.0.0
%project=flipr
%uri=https://github.com/sqitchers/sqitch-snowflake-intro/

appschema 2018-07-27T14:27:24Z Marge N. O’Vera <marge@example.com> # Add schema for all flipr objects.
users [appschema] 2018-07-27T15:03:56Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
flips [appschema users] 2018-07-27T15:23:41Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
userflips [appschema users flips] 2018-07-27T15:23:50Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.
@v1.0.0-dev1 2018-07-27T15:40:25Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1.

lists [appschema flips] 2018-07-27T16:00:00Z Marge N. O’Vera <marge@example.com> # Adds table for storing lists.
hashtags [flips] 2018-07-27T15:51:16Z Marge N. O’Vera <marge@example.com> # Adds table for storing hashtags.

Note that it has appended the changes from the merged "lists" branch, and then
merged the changes from our "hashtags" branch. Test it to make sure it works
as expected:

> sqitch rebase -y
Reverting all changes from flipr_test
- hashtags ................ ok
- userflips @v1.0.0-dev1 .. ok
- flips ................... ok
- users ................... ok
- appschema ............... ok
Deploying changes to flipr_test
+ appschema ............... ok
+ users ................... ok
+ flips ................... ok
+ userflips @v1.0.0-dev1 .. ok
+ lists ................... ok
+ hashtags ................ ok

Note the use of L<C<rebase>|sqitch-rebase>, which combines a
L<C<revert>|sqitch-revert> and a L<C<deploy>|sqitch-deploy> into a single
command. Handy, right? It correctly reverted our changes, and then deployed
them all again in the proper order. So let's commit F<.gitattributes>; seems
worthwhile to keep that change:

> git add .
> git commit -m 'Add `.gitattributes` with union merge for `sqitch.plan`.'
[hashtags 86596a9] Add `.gitattributes` with union merge for `sqitch.plan`.
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 .gitattributes

=head2 Merges Mastered

And now, finally, we can merge into C<master>:

> git checkout master
Switched to branch 'master'
> git merge --no-ff hashtags -m "Merge branch 'hashtags'"
Merge made by the 'recursive' strategy.
.gitattributes | 1 +
deploy/hashtags.sql | 9 ++++++++++
revert/hashtags.sql | 4 ++++
sqitch.plan | 1 +
verify/hashtags.sql | 4 ++++
5 files changed, 19 insertions(+)
create mode 100644 .gitattributes
create mode 100644 deploy/hashtags.sql
create mode 100644 revert/hashtags.sql
create mode 100644 verify/hashtags.sql

And double-check our work:

> cat sqitch.plan
%syntax-version=1.0.0
%project=flipr
%uri=https://github.com/sqitchers/sqitch-snowflake-intro/

appschema 2018-07-27T14:27:24Z Marge N. O’Vera <marge@example.com> # Add schema for all flipr objects.
users [appschema] 2018-07-27T15:03:56Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
flips [appschema users] 2018-07-27T15:23:41Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
userflips [appschema users flips] 2018-07-27T15:23:50Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.
@v1.0.0-dev1 2018-07-27T15:40:25Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1.

lists [appschema flips] 2018-07-27T16:00:00Z Marge N. O’Vera <marge@example.com> # Adds table for storing lists.
hashtags [flips] 2018-07-27T15:51:16Z Marge N. O’Vera <marge@example.com> # Adds table for storing hashtags.

Much much better, a nice clean master now. And because it is now identical to
the "hashtags" branch, we can just carry on. Go ahead and tag it, bundle, and
release:

> sqitch tag v1.0.0-dev2 -n 'Tag v1.0.0-dev2.'
Tagged "hashtags" with @v1.0.0-dev2
> git commit -am 'Tag the database with v1.0.0-dev2.'
[master 1c67e0d] Tag the database with v1.0.0-dev2.
1 files changed, 1 insertion(+)
> git tag v1.0.0-dev2 -am 'Tag v1.0.0-dev2'
> sqitch bundle --dest-dir flipr-1.0.0-dev2
Bundling into flipr-1.0.0-dev2
Writing config
Writing plan
Writing scripts
+ appschema
+ users
+ flips
+ userflips @v1.0.0-dev1
+ lists
+ hashtags @v1.0.0-dev2

Note the use of the C<--dest-dir> option to C<sqitch bundle>. Just a nicer way
to create the top-level directory name so we don't have to rename it from
F<bundle>.

=head1 More to Come

Sqitch is a work in progress. Better integration with version control systems
Expand Down
2 changes: 1 addition & 1 deletion lib/sqitchtutorial-sqlite.pod
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Make sure we can
Note the use of C<--show-tags> to show all the deployed tags. Make sure we can
revert, too:

> sqitch revert --to @HEAD^ -y
Expand Down
3 changes: 2 additions & 1 deletion lib/sqitchtutorial-vertica.pod
Original file line number Diff line number Diff line change
Expand Up @@ -917,12 +917,13 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Make sure we can
Note the use of C<--show-tags> to show all the deployed tags. Make sure we can
revert, too:

> sqitch rebase -y --onto @HEAD^
Reverting changes to userflips @v1.0.0-dev1 from flipr_test
- hashtags .. ok
> sqitch deploy
Deploying changes to flipr_test
+ hashtags .. ok

Expand Down
2 changes: 1 addition & 1 deletion lib/sqitchtutorial.pod
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ Look good?
#
Nothing to deploy (up-to-date)

Note the use of C<--show tags> to show all the deployed tags. Now make it so:
Note the use of C<--show-tags> to show all the deployed tags. Now make it so:

> git add .
[flips e8f4655] Add flips table.
Expand Down

0 comments on commit 1f9b7a5

Please sign in to comment.