►
Description
A 1-hour training video for contributors new to GitLab and Gitaly.
fixing a locally broken Ruby gem C extension by recompiling, demo of how creating a MR across forks causes new commits to suddenly appear in the fork parent repository, deep dive into the FetchSourceBranch RPC, adding debug code to see
how address and authentication metadata is passed down to
gitaly-ruby, failed attempt to log gitaly-ssh arguments, comparison
of gitaly-ssh and gitlab-shell, a Gitaly server can end up making RPC calls to itself.
Recorded 2019-03-21
A
Hello
welcome
everyone
to
I
believe
the
fifth
Catholic
training
session
by
now
today,
we're
going
to
look
at
some
things
that
happen
during
git
merge
and
the
perspective
we're
looking
from
is
from
AG
Italy
engineer,
so
someone
who
knows
the
quickly
project
but
wants
to
understand
how
it
fits
into
the
larger
picture
of
kit
lab
I
think
this
is
also
interesting
if
you're
looking
at
stuff
from
a
different
angle.
But
this
is
the
angle
when
I
approach
it
from
so
merge
requests.
A
Let's,
let's
make
a
merge
request
and
then
I
can
point
out
the
things
that
I
want
to
look
at.
This
is
my
GDK
I
hope
we
can
see
this
and
I
have
the
gait
lab
test
project
here
and
I'm
going
to
fork
this,
because
things
get
more
interesting
when
we
work
across
Forks.
So
we
just
want
to
start
out
and
that's
scenario.
A
A
A
A
Okay,
the
back
button,
is
also
slow,
well
development
mode.
Okay,
here
we
are
so
group
three
is
the
forked
lap
work
is
the
original
project
that
we
forked
from
I'm
going
to
edit
a
file?
Let's
say
I
want
to
edit
the
changelog.
Maybe
that's
also
a
bad
idea.
If
the
change
logo
is
long,
it's
probably
not
well,
it's
not
long,
because
I
guess
I
go
for
this
file
more
often,
if
I
want
to
edit
something.
The
original
content
of
the
change
mark
was
not
misspelled.
Whatever,
let's
fix
the
spelling
and
let's.
A
A
A
Tell
you
already
what
I
want
to
show
I
want
to
show
that
this
editor
gestates
created
a
committee
in
the
fork,
but
that
committee
does
not
exist
in
the
parents.
Actually,
it's
good
that
I
didn't
create
the
merge
request
straight
away,
because
that
would
have
brought
me
of
the
opportunity
to
show
that
the
committee
doesn't
automatically
go
to
the
parents.
A
And
so
that
that
is
what
the
one
thing
I
want
to
show
you
ever
commits
in
one
project
and
how,
when
it
gets
merged,
it
eventually
has
to
end
up
in
the
parent
project.
So
how
does
it
get
there?
And
the
other
thing
I
want
to
look
at
is
the
fact
that
the
merge
commits
has
my
name
on
it
me,
the
user,
and
how
does?
How
did
that
happen?
C
A
So
that's
the
commit
I
just
made
and
let's
see
if
that
committee
exists
in
the
parent
project
already
so
here
we
have
a
commit.
You
are
L
and
we're
in
group
3
I'm
just
going
to
change
that
group
name
and
I
get
a
404.
So
thanks
for
the
question-
and
so
this
was
the
first
point-
I
wanted
to
make.
We
get
a
404,
but
I
am
going
to
curate.
This
Bert
requests
my
favorite
requests.
It's
not
yeah.
B
A
C
A
C
B
C
A
A
And
yes,
we're
on
good
luck,
work
now,
so
here's
the
merch
requests
now
remember.
This
is
the
window
where
I
add
the
404
on
the
commits
I'm
refreshing
it
now
and
I
expect
this
two
loads,
because
the
commit
now
exists
in
the
repository.
So
this
is
magic
thing
number
one.
The
commits
existed
only
existed
in
one
repository
now
it's
appeared
in
this
one,
even
though
we
haven't
merged
yet
now.
The
second
thing
is
that
when
I
merge.
A
Maybe
do
these
demos
on
only
this
instance,
because
that
would
be
much
faster,
except
I'm.
Making
life
changes
is
a
bit
harder.
So
here
it
says,
I
just
pushed
to
the
master
branch,
but
I
didn't
so.
How
did
that
end
up
there?
And
we
saw
in
previous
videos
that
these
notifications,
these
events,
come
from
the
git
hooks.
So
it's
like
a
push
happens
except
I.
Didn't
do
a
push.
That's
the
second
thing.
I
want
to
look
at
so
now
that
I
got
that
demo.
A
A
Guess
I
just
said
what
the
order
is
going
to
be
that
we're
going
to
look
at
this.
So
how
does
the
fork
end
up
in
the
target
project?
What
happens
there
is
that
the
moments
I
created
the
merge
requests.
We
kicked
off
an
async
job
somewhere
that
tries
to
call
a
get
Li
RPC
called
fetch
source
fetch
source
source
branch.
Let's
see
if
we
can
find
that.
A
A
A
C
A
Target
ref
in
the
current
repository,
so
the
current
ripple
support
the
repository
would
be
kid
lab
or
kid
lab
tests,
and
this
one
would
be
group
3
get
lab
tests
and
this
one
would
have
been
mr1
and
I'm
not
entirely
sure
what
this
was.
Maybe
this
was
refs
had
master
or
no,
it's
not
mastered
that
would
have
been
emerged.
I
think
it
goes
into
a
temporary,
a
special
temporary
ref
on
the
repo.
A
A
Yeah,
so
that's
got
the
murse
requests
and
I
expect
it
to
be
one
of
these.
Let's
see
what
our
commit
ID
was.
That
was
something
see
59
4
there
we
go
so
this
would
have
been
merged
requests
9
head,
so
this
is
this
is
what
happens
behind
the
scene
and
something
called
this:
do
we
want
to
trace
back
what
called
this
or
do
we
want
to
look
at
what
this
RPC
does?
A
I
think
just
what
it
does?
Okay,
so
yeah?
What?
How
does
this
work,
because
that's
kind
of
unexpected
if
you've
never
seen
this
stuff
before?
Let's
see
this
is
a
Phet
source
parent
request.
This
goes
from
ticket
Lee
client
of
Cole
yeah.
Let's
just
look
at
the
get
Lee
code.
Next
I
will
have
to
come
back
to
this
later
because
there
are
some
interesting
things
here:
pet
stores
branch.
So
that
would
be
what
I
do
so.
A
I
know
that
these
things-
okay,
so
this
tells
me
with
the
name
of
the
RPC-
is
in
underscore
case
whatever
they
call
that
and
I
know
that
the
RPC
name
in
the
go
code
is
camel
not
camel
case.
It's
just
upper
upper
case,
so
I
would
for
fetch
source
branch
without
the
underscores.
This
is
a
mental
translation.
You
have
to
do
all
the
time
if
you
want
to
look
on
the
Gately
side
and
then
jump
over
to
the
real
side
or
back
because
the
calling
convention
is
different
and
Gigi
is
my
kid.
A
Crap
shortcut
and
I
was
restricted
to
the
internal
directory,
because
if
you
do
a
good
crap
or
the
full
repo
you
get
defender
directory
and
the
vendor
director
is
full
of
boilerplate
code.
That
makes
no
sense
now,
with
this
I
get
a
targeted
results.
Oh
this
is
test
codes,
so
we
can
ignore
that,
and
this
is
the
actual
definition
and
it's
suspiciously
shorts,
and
that's
because
this
is
just
forwarding
the
request
to
get
Li.
Ruby
have
I
talked
about
it.
A
Lately,
ruby
in
these
videos
before
I,
so
goodly
Ruby,
is
a
sidecar
of
the
main
Catelli
process,
which
is
just
another
gar
PC
server
setting
amends
the
server
site
of
the
Gately
protocol,
but
it
only
implements
the
subsets
that
for
legacy
or
other
reasons,
is
in
Ruby
instead
of
Ingo.
All
this
does.
Is
it
propagates?
The
request
to
Ruby
and
it
will
copies
the
response
back,
so
this
is
a
empty
implementation.
A
A
We
have
a
request,
objects
and
we
are
backing
it
here.
We're
getting
out
the
source
repository
interesting
with
leeway
to
do
with
the
call
here
and
we're
getting
the
repository
that
we're
operating
on
to
the
Cir
posturing,
we're
fetching
data
into,
and
then
we
call
this
methods
further
down
in
Gately
ruby,
which
returns
some
sort
of
results.
So
let's
look
what
that
method
is
doing
and
I'm
going
to
just
use
my
search
result
here
and
there's
a
fetch
source
branch
bang
here.
So
that's
probably
what
we're
doing?
Oh.
A
Again,
yeah
repository
source
branch,
ref-
okay,
yes,
that's
to
one
local
ref.
Okay,
that
goes
into
another
methods
which
amusingly
not
actually
I,
think
it
actually
used
I'm,
not
sure
if
they're
still
uses
Rockets.
So
the
fact
that
is
this
called
record
underscore
fetch
source
branch.
It's
just
a
leftover
of
the
migration
projects.
A
This
uses
something
called
with
repo
branch
commits
and
then
that
deals
the
commits
or
it
does
not
use
the
commits.
Why
is
there
an
if
here?
Well
there's
this
source
branch?
This
might
be
an
invalid
branch
like
the
branch
might
have
just
gotten
deleted.
It
might
not
exist
at
all.
If
that's
the
case,
then
we
get
an
ill
object
here
and
we
end
up
in
this
else
branch.
But
if
the
comment
was
found,
then
this
thing
is
updating
the
local
ref
to
the
commit
ID.
So
that
seems
straightforward
enough.
A
So
the
local
ref
was
this
thing,
so
refs
merge,
requests
nine
heads
and
that's
God's,
updated
to
the
commit
ID
that
this
branch
points
to
in
the
other
rep
in
the
dark
in
the
source.
Repository
question
is:
what
is
this
thing?
Are
you
still
with
me
so
far,
yeah,
okay,
so
with
repo
branch
commits
I'm
just
going
to
use
the
search
function
of
my
editor
and
that
they
starts
process
or
even
start
branch
name,
and
this
instant
stenchy
AIT's
a
remote
repository
if
necessary,
unless
it
already
is
a
remote
repository,
it
does
check.
A
A
As
you
can
see,
this
one
is
the
subclass
Gately
remote
repository
is
a
subclass
of
remote
repository,
but
to
understand,
what's
going
on,
you
actually
need
to
know,
look
at
both
files
because
they
interact
with
each
other.
This
is
maybe
not
necessary
anymore.
This
is
again
some
technical
debt
from
the
migration
projects,
because
during
the
migration
projects,
we
were
not
always
interacting
with
this
one
and
we
had
an
alternative
implementation
of
this
one.
Actually,
this
is
the
alternative
implementation,
so.
A
Yeah,
you
have
to
read,
read
both
of
them,
but
so
what
this
thing
is
doing
is
it's
actually
making
goodly
requests
here?
You
can
see
that
we
instantiate,
essentially
it
stubs,
so
it
isn't
just
the
check
of
a
branch
exists.
This
looks
in
the
commit
servers
to
see
if
we
can
look
up
a
commits.
Actually,
so
that's
yeah,
it's
a
fine,
commit
RPC
and
then
so
that
this
preparatory
work
and
then
the
final
transfer
of
gets
data.
Okay.
Now
we
need
to
go
back
to
the
repository
RB.
A
A
A
A
A
A
C
A
A
A
A
C
C
A
Think
at
the
time
of
the
Gateway
migration
project,
when
we
were
dealing
with
these
are
pcs.
It
was
already
the
case
that
such
source
branch
was
called
independently
of
creating
the
actual
merger.
Comets.
So
I,
don't
know
the
exact
timing,
but
the
idea
that
the
fetching
is
separate
from
trading
the
merge
commits
is
has
been
it
that
way
for
at
least
two
years
now:
I
guess
for
yeah,
one
or
a
year
and
a
half
or
more
okay.
A
A
From
temper
F
yield
commit
to
caller
delete
the
temporary
reference,
and
so
the
caller
of
this
thing
then
decides
to
create
reference.
That's
points
to
the
commits,
and
that
way
we've
remember
where
the
commit
is,
but
we
have
the
freedom
to
back
out
and
forget
that
this
commit
existed
and
then
it
will
eventually
get
garbage
collected.
A
So
the
fetch
is
actually
a
git
fetch
that
fetches
from
what
looks
like
an
ssh
URL
but
uses
a
custom,
get
leak
transports
to
fetch
from
another
Gately
server.
So
this
is
the
part
I
wanted
to
get
to.
So
when
the
data
transfer
happens
because
essentially
the
fetch
is
it
fetch,
so
that
would
be
that
is
a
fake,
fake
URL
and
then
it's
fetches
RF
from
their
remote
site.
A
A
A
And
if
you
set
that
on
your
gate,
if
you
set
that
environment
variable
before
you
run,
git,
clone
or
git
fetch,
then,
instead
of
trying
to
connect
to
the
other
end
with
SSH
gates,
will
just
run
that
command
and
assume
that
it
establishes
a
session
for
you,
and
that
is
how
we
got
this
working,
so
we're
using
a
normal
gait
fetch
command
and
we're
so
we're
using
native
kids
to
do
this
fetch,
but
the
underlying
transports
is
actually
a
native
of
quitly
RPC.
So
what
happens
at
this
point
is
so
we
use
this.
A
A
What
is
the
commit
ID
do
I
have
to
commit
ID,
then
I
don't
need
to
fetch
it.
All
that
stuff
makes
calls
makes
that
workhorse.
So
we're
actually
looking
at
to
get
early
clients
here
quickly.
Ruby
itself
is
a
client,
and
that
is
the
code.
I
was
showing
you
earlier.
That
was
the
giggly
remote
repository
class.
Where
did
I
throw
that?
A
A
B
A
Be
showing
you
this
because
this
part
works
it's
there.
The
important
thing
to
remember
is
that
this
happens
and
it
might
be
nice.
If
we,
let's
see,
can
we
log
okay
I,
do
want
to
look
at
this
because
I
want
to
log
for
you
what
this
looks
like,
but
it's
the
nicest
way
to
do
that.
I
think
the
nicest
way
to
do
that
is
on
the
clients.
Let's
go
back
to
the
clients
that
would
be
here.
A
A
B
A
So
the
logging
is
working,
you
can
see
a
get,
Li
call
happening.
Let's
look
for
a
moment
what
this
is
so
here
you
can
see
that
we
use
that
authentication
did
so.
This
is
not
an
intricately
call,
yet
this
is
just
a
normal
call,
but
the
authorization
gets
bastard
in
the
metadata
and
some
stuff
where
we
identify
ourselves
as
the
rails.
App,
we
get
a
correlation
ID.
A
A
Just
maybe
a
bit
much,
let's
see
if
I
can
find
I
hope
we
can
find
the
one
yes
I,
just
also
think
I
think
I
saw
something
where
the
thing
was
bigger.
Yes,
here
we
go
so
this
is
where
we're
doing
fetch
source
branch
and
let's
look
at
the
metadata,
so
we
have
two
normal
authentic
author
authentication
token
some
stuff
about
the
client
name.
This
is
what
we
care
about.
Let's
split
out
the
rests.
A
A
A
B
A
A
A
B
A
To
our
riddle,
I
think
this
is
returning
a
null
and
if
we
would
have
a
null
check
here,
we
could
return
early
and
just
say
there
is
no
token,
but
instead
it's
acting
as
if
the
token
is
the
empty
string
and
this
gets
ignored
by
the
server.
Because
this
we
just
looked
at
the
server
config
file
and
there
we're
not
expecting
it.
Okay,.
B
A
A
This
is
that
you
see
there
are
two
get
any
clients
in
action
here
that
you
might
not
know
even
exists
because
they
are
hidden
inside
Keithley
itself
and,
like
I
said,
the
one
is
caitli
ruby,
which
is
a
client
that
will
make
calls
to
any
of
a
guilty
server
in
your
kidnap
and
the
other
is
called
get
the
SSH.
So
let's
go
back
to
a
goodly
window
and
let's
look
under
CMD,
so
there
we
have
get
the
SSH
now
this
is
the
other
client,
and
this
thing
gets.
It
takes
it's
a
information
from
environment
variables.
A
B
A
A
A
A
A
A
A
B
A
A
A
A
A
A
A
A
A
Yeah,
so
this
is
a
separate
executable.
It's
indicate
Lee
repo,
at
least,
and
you
may
have
seen
that
at
the
top
left
of
the
Keithley
repo.
There
is
this
subdirectory
called
client,
and
that
is
a
gr
PC
client
specifically
made
for
connecting
to
Catelli.
So
the
Gately
SSH
executables,
you
reusing
that
Co
clients
and
the
it's
actually
reusing
a
lot
of
how
great
lab
shell
works
so
because
in
get
lab
shell
we're
doing
okay,
let's
end
with
that.
So
if
you
think
back
to
SSH
SSH,
so
what
you
have
there,
you
have
get.
A
A
A
You
have
sh
t
you
have
to
get
lab
shell
parts
and
then
that
is
acting
as
a
catalyst
lines
and
copying
data
back
and
forth,
and
we
just
directly
spawn
the
server-side
parts
of
the
kids
ssh
the
way
gate
ssh
is
implemented
in
gait
lab.
We
spawn
that
directly
plug
that
in
to
get
fetch
and
because
get
fetch
is
in
this
case
running
on
a
Keithley
server.
It
has
network
access
to
the
other
Gately
servers
and
we
can
get
away
with
this.
C
A
Do
that
so
the
RPC
is
called
SSH
uploads
back
that's
for
the
the
fetched
case.
The
other
direction
is
called
SSH
received
back
so
yeah.
We
have
good
fashion
that
spawns
quickly
SSH
and
that
makes
an
RPC
connection
to
get
the
wherever
quickly,
where
exactly
and
that
spawns
its
uploads
back
and
of
course,
here
we
have
Italy
ruby,
which
spawns
that
thing
and
we
have
Italy.
C
A
A
A
No
I
mean
that
these
might
be
different
machines
at
different
Network
addresses
what
yeah
that's
right,
because
in
the
general
case
on
Caitlyn
comb,
the
fork
might
be
on
a
completely
different
skill,
a
server,
and
it's
also
worth
noting.
That's
sorry
for
that
noise.
It's
worth
noting
that
the
way
we
designed
this,
even
in
GDK,
where
there
is
no
goodly
one
and
there's
only
one
gotelli
process
as
long
as
the
source
you're
going
across
a
fork.
It
already
makes
a
network
connection.
A
We
intentionally
design
it
like
that,
so
that
this
whole
network
stuff
gets
exercised
more
because
if
it's
a
mechanism
that
only
kicks
in,
we
have
to
quickly
servers-
and
you
can
have
bugs
that
you
don't
find
out
about
unless
you
have
to
get
Li
servers
and
it
already
kicks
in
with
one
Gately
server.
So
that
thing
is
then
actually
making
a
connection
to
itself
and
it
that
has
to
be
authenticated.
So
it
gets
the
authentication
all
the
way
back
from
catalepsy.