ITメンティーの補助輪

駆け出しメンティーの自分と、日本のどこかにいる誰かのための補助輪

LearnGitBranchingを最後まで「日本語」で学習する補助輪

Gitの様々なコマンドをパズルゲーム感覚で学べるオープンソースの学習サイト「LearnGitBranching」では、有志の方々によって日本語翻訳版が提供されています。

Git初心者、且つ、英語が苦手な自分にとって非常に有り難いサービスなのですが、Gitリモート編のレベル8から一部のレッスン(Level)は英語版のみとなっています😢

今回、「Google翻訳」「DeepL翻訳」「英語がペラペラな方達のサイト」を参考になんとか完走したのですが、もしかすると自分と同じように英語の壁に躓いてしまう方がいるかもしれないと思い、「仮の日本語版」という形で執筆してみました。

この記事が日本のどこかにいるかもしれない「英語が苦手だけどLearnGitBranchingを最後までやり抜きたい方」の元に届くと嬉しいです。

「日本語も英語もGitもGitHubも得意だよ」という神様へ

神様! 日本語版への翻訳にご協力いただくことで日本中の😭(悲し涙)が😭(嬉し涙)に変わります。ぜひとも以下のGitHubにてご協力いただけますと幸いです🙏


どのレッスン(Level)の日本語化が未完了?

6つのレッスン(Level)で日本語化が未完了となっていました。
(2020/12/04現在の情報です)

セクション レッスン(Level) 日本語化
Gitリモート 1 〜 7 完了
Gitリモート 8: Locked Master 未完了
Gitリモート上級編 1: Push Master! 完了
Gitリモート上級編 2: リモートとのmerge 完了
Gitリモート上級編 3: リモートのトラッキング 完了
Gitリモート上級編 4: Git pushの引数 未完了
Gitリモート上級編 5: Git pushの引数 -- 拡張編 未完了
Gitリモート上級編 6: Fetchの引数 未完了
Gitリモート上級編 7: 無のsource 未完了
Gitリモート上級編 8: Pullの引数(最後のLevel) 未完了

この記事の構成

日本語化が「未完了」となっているLevelの、

  • 翻訳対象となるポップアップ画像
  • 原文と翻訳後のテキスト

でお送りします🙂

  • 補足
    • Gitがコマンドライン上に出力するメッセージは原文のままとさせていただきました
    • 翻訳後、そのままの方が良いように感じた箇所は「翻訳前の名称」に戻しました
      • 【例】master → マスター → master 等
    • 翻訳後、どうしても違和感のある箇所は自分なりに調べて再翻訳しました
      • 原文にスラングが多かったため、この作業にかなり苦労しました…!
    • 【master】について

Gitリモート | 8: Locked Master

Remote Rejected! / リモート拒否!

If you work on a large collaborative team its likely that master is locked and requires some Pull Request process to merge changes. If you commit directly to master locally and try pushing you will be greeted with a message similar to this:

大規模なコラボレーションチームで作業している場合、masterがロックされている可能性が高く、その場合は変更をマージするためにプルリクエストのプロセスが必要となります。masterがロックされている環境でローカルのmasterに直接コミットしてプッシュしようとすると、次のようなメッセージが表示されます。

#=> ! [remote rejected] master -> master \
#   (TF402455: Pushes to this branch are not permitted; \
#   you must use a pull request to update this branch.)

Why was it rejected? / なぜ拒否されたのですか?

The remote rejected the push of commits directly to master because of the policy on master requiring pull requests to instead be used.

プルリクエストの使用を要求する「masterに関するポリシー」にひっかかったためです。そのため、リモートはmasterへの直接コミットのプッシュを拒否しました。

You meant to follow the process creating a branch then pushing that branch and doing a pull request, but you forgot and committed directly to master.

ブランチを作成し、そのブランチをプッシュしてプルリクエストを実行するプロセスに従うつもりでしたが、masterを忘れて直接コミットしてしまいました(というシナリオ)。

Now you are stuck and cannot push your changes.

今あなたは立ち往生していて、変更をプッシュすることができません…。


The solution / 解決方法

Create another branch called feature and push that to the remote. Also reset your master back to be in sync with the remote otherwise you may have issues next time you do a pull and someone else's commit conflicts with yours.

featureと呼ばれる別のブランチを作成し、それをリモートにプッシュしてください。また、masterをリセットしてリモートと同期させます。そうしないと、次にプルを実行したときに問題が発生し、他の誰かのコミットがあなたのコミットと競合する可能性があるためです。


コマンドライン上の説明

Make the feature branch from the local master before resetting it back to be the same as origin's master

オリジンのmaster(o/master)と同じになるように、リセットする前にローカルのmasterからfeatureブランチを作成しましょう。

(ちなみに)
コマンドライン上の説明」については、このLevel以外の日本語化が全て完了していました🙂


Gitリモート上級編 | 4: Git pushの引数

Push arguments / プッシュの引数

Great! Now that you know about remote tracking branches we can start to uncover some of the mystery behind how git push, fetch, and pull work.

素晴らしい!リモート追跡ブランチについて理解したので、git push、fetch、pullがどのように機能するのか、背後にあるいくつかの謎を明らかにしていきましょう。

We're going to tackle one command at a time but the concepts between them are very similar.

ここでは1つずつコマンドに取り組むことになりますが、それらの間の概念は非常によく似ています。

First we'll look at git push. You learned in the remote tracking lesson that git figured out the remote and the branch to push to by looking at the properties of the currently checked out branch (the remote that it "tracks").

まず、git pushについて見ていきます。リモート追跡ブランチのレッスンで、gitが現在チェックアウトされているブランチ(リモート追跡ブランチ)のプロパティを確認することで、プッシュ先のリモートとブランチを把握できることを学びました。

This is the behavior with no arguments specified, but git push can optionally take arguments in the form of:

これは引数が指定されていない動作でしたが、git pushはオプションで次の形式の引数を受け取ることができます。

git push <remote> <place>

What is a <place> parameter you say? We'll dive into the specifics soon, but first an example. Issuing the command:

<place>パラメータとは何でしょうか? 詳細についてはすぐに詳しく説明しますが、まずは例を見てみましょう。コマンドを実行します:

# git push <remote> <place>
$ git push origin master

translates to this in English:

これを英語に翻訳します(※訳註: 「これを言葉で説明します」的な意味だと思います):

『Go to the branch named "master" in my repository, grab all the commits, and then go to the branch "master" on the remote named "origin". Place whatever commits are missing on that branch and then tell me when you're done.』

リポジトリ内の「master」という名前のブランチに移動し、すべてのコミットを取得してから、「origin」という名前の「リモートのmasterブランチ」に移動します。不足しているコミットをそのブランチに配置し、完了したら教えてください。』

By specifying master as the "place" argument, we told git where the commits will come from and where the commits will go. It's essentially the "place" or "location" to synchronize between the two repositories.

<place>の引数としてmasterを指定することで、コミットがどこから来てどこへ行くのかをgitに伝えました。基本的に、2つのリポジトリ間で同期するのは「place(場所)」または「location(位置)」です。

Keep in mind that since we told git everything it needs to know (by specifying both arguments), it totally ignores where we are checked out!

gitに(両方の引数を指定して)必要なすべてのことをgitに伝えたので、チェックアウトされた場所を完全に無視することに注目してください!


Let's see an example of specifying the arguments. Note the location where we are checked out in this example.

引数を指定する例を見てみましょう。この例でチェックアウトされている場所に注目してください。

$ git checkout C0
$ git push origin master

There we go! master got updated on the remote since we specified those arguments.

うまくいきました!これらの引数を指定したため、masterはリモートで更新されました。


What if we hadn't specified the arguments? What would happen?

引数を指定しなかった場合は?どうなるでしょうか?

$ git checkout C0
$ git push

The command fails (as you can see), since HEAD is not checked out on a remote-tracking branch.

ご覧のとおり、HEADがリモート追跡ブランチでチェックアウトされていないため、コマンドは失敗します。


Ok, for this level let's update both foo and master on the remote. The twist is that git checkout is disabled for this level!

さて、このレベルでは、リモートのfooとmasterの両方を更新しましょう。厄介ごとと言えば、このレベルではgit checkoutが無効になっていることです!

Note: The remote branches are labeled with o/ prefixes because the full origin/ label does not fit in our UI. Don't worry about this... simply use origin as the name of the remote like normal.

Note: 完全なorigin/ラベルがUIに収まらないため、リモートブランチにはo/プレフィックスが付けられます。これについて心配する必要はありません。通常のようにリモートの名前としてoriginを使用するだけです。


Gitリモート上級編 | 5: Git pushの引数 -- 拡張編

<place> argument details / <place>引数の詳細

Remember from the previous lesson that when we specified master as the place argument for git push, we specified both the source of where the commits would come from and the destination of where the commits would go.

前のレッスンで、git pushのplace引数としてmasterを指定したときに、コミットの送信元と送信先の両方を指定したことを思い出してください。

You might then be wondering -- what if we wanted the source and destination to be different? What if you wanted to push commits from the foo branch locally onto the bar branch on remote?

あなたは疑問に思うかもしれません -- ソースと宛先を異なるものにしたい場合はどうでしょうか。ローカルのfooブランチからリモートのbarブランチにコミットをプッシュしたい場合はどうなるのでしょうか?

Well unfortunately that's impossible in git... just kidding! Of course it's possible :)... git has tons and tons of flexibility (almost too much).

Let's see how in the next slide...

残念ながら、それはgitでは不可能です...冗談です!もちろん、それは可能です :) ... gitには多大な柔軟性があります(あまりにも多くの)。

次のスライドでその方法を見てみましょう...


In order to specify both the source and the destination of <place>, simply join the two together with a colon:

<place>の送信元と宛先の両方を指定するには、コロンで結合するだけです。

$ git push origin <source>:<destination>

This is commonly referred to as a colon refspec. Refspec is just a fancy name for a location that git can figure out (like the branch foo or even just HEAD~1).

これは一般に「コロンrefspec」と呼ばれます。refspecは、gitが把握できる場所の単なる名前です(ブランチ fooや単にHEAD〜1など)。

Once you are specifying both the source and destination independently, you can get quite fancy and precise with remote commands. Let's see a demo!

ソースと宛先の両方を個別に指定すると、リモートコマンドを使用して非常に凝った正確なものを得ることができます。デモを見てみましょう!


Remember, source is any location that git will understand:

sourceはgitが理解できる場所であることを忘れないでください:

# git push origin <source>:<destination>
% git push origin foo^:master

Woah! That's a pretty trippy command but it makes sense -- git resolved foo^ into a location, uploaded whatever commits that weren't present yet on the remote, and then updated destination.

おぉぉ!これはかなりトリッピー(奇妙)なコマンドですが、それは理にかなっています -- gitはfoo^で場所を把握し、リモートにまだ存在していないコミットをアップロードしてから、宛先を更新しました。


What if the destination you want to push doesn't exist? No problem! Just give a branch name and git will create the branch on the remote for you.

プッシュしたい宛先が存在しない場合はどうなるでしょうか?問題ありません!ブランチ名を付けるだけで、gitがリモートにブランチを作成します。

# git push origin <source>:<destination>
$ git push origin master:newBranch

Sweet, that's pretty slick :D

いい感じです :D


For this level, try to get to the end goal state shown in the visualization, and remember the format of:

このレベルでは、ゴールの図に表示されている状態に到達し、次の形式を覚えておいてください。

<source>:<destination>


Gitリモート上級編 | 6: Fetchの引数

Git fetch arguments / Gitのfetch引数

So we've just learned all about git push arguments, this cool <place> parameter, and even colon refspecs (<source>:<destination>). Can we use all this knowledge for git fetch as well?

ここまでで、git pushの引数、クールな <place>パラメータ、さらにはコロンrefspecs( <source>:<destination>)についてすべて学習しました。このすべての知識は git fetchにも使用できるでしょうか?

You betcha! The arguments for git fetch are actually very, very similar to those for git push. It's the same type of concepts but just applied in the opposite direction (since now you are downloading commits rather than uploading).

もちろんです! git fetchの引数は、実際にはgit pushの引数と非常によく似ています。 これは同じタイプの概念ですが、反対方向に適用されます(今はアップロードではなくコミットをダウンロードしているので)。

Let's go over the concepts one at a time...

概念を1つずつ見ていきましょう...

The <place> parameter / <place>パラメータ

If you specify a place with git fetch like in the following command:

次のコマンドのように、git fetchで場所を指定した場合:

$ git fetch origin foo

Git will go to the foo branch on the remote, grab all the commits that aren't present locally, and then plop them down onto the o/foo branch locally.

Gitはリモートの fooブランチに移動し、ローカルに存在しないすべてのコミットを取得してから、それらをローカルのo/fooブランチに配置します。

Let's see this in action (just as a refresher).

これが実際に動作していることを見てみましょう(復習)。

By specifying a place...

場所を指定して...

$ git fetch origin foo

We download only the commits from foo and place them on o/foo.

fooからコミットのみをダウンロードしてo/fooに配置します。


You might be wondering -- why did git plop those commits onto the o/foo remote branch rather than just plopping them onto my local foo branch? I thought the <place> parameter is a place that exists both locally and on the remote?

不思議に思うかもしれません。なぜgitはそれらのコミットをローカルの fooブランチに配置せず、o/fooリモートブランチに配置したのでしょう? <place>パラメータはローカルとリモートの両方に存在する場所だと思いませんか?

Well git makes a special exception in this case because you might have work on the foo branch that you don't want to mess up!! This ties into the earlier lesson on git fetch -- it doesn't update your local non-remote branches, it only downloads the commits (so you can inspect / merge them later).

このケースでは、gitは特別な例外を作成します。なぜならこのとき「fooブランチで作業している可能性」があり、その場合は作業が台無しになってしまうためです。これは、 git fetchに関する前のレッスンと結びついています。-- ローカルの非リモートブランチは更新せず、コミットをダウンロードするだけです(後からそれらを検証したりマージできます)。


"Well in that case, what happens if I explicitly define both the source and destination with <source>:<destination>?"

『その場合、<source>:<destination>で明示的に定義するとどうなりますか?』

If you feel passionate enough to fetch commits directly onto a local branch, then yes you can specify that with a colon refspec. You can't fetch commits onto a branch that is checked out, but otherwise git will allow this.

ローカルブランチに直接コミットをフェッチしたいという「熱意」があるなら、コロンrefspecで指定することができます。チェックアウトされているブランチにコミットをフェッチすることはできませんが、それ以外の場合はgitで許可されます。

Here is the only catch though -- <source> is now a place on the remote and <destination> is a local place to put those commits. It's the exact opposite of git push, and that makes sense since we are transferring data in the opposite direction!

ただし、ここで唯一の注意点が。<source>はリモート上の場所になり、<destination>はそれらのコミットを配置するローカルな場所になりました。git pushの正反対であり、データを逆方向に転送しているのですから、これは理にかなっているのですが。

That being said, developers rarely do this in practice. I'm introducing it mainly as a way to conceptualize how fetch and push are quite similar, just in opposite directions.

とは言え、開発者が実際にこれを行うことは滅多にありません。ここでは主に「fetchpushがどのように似ているのか」を概念化する方法として、この動作を紹介します。


Let's see this craziness in action:

では、この「狂気の沙汰」を実際に見てみましょう:

$ git fetch origin foo~1:bar

Wow! See, git resolved foo~1 as a place on the origin and then downloaded those commits to bar (which was a local branch). Notice how foo and o/foo were not updated since we specified a destination.

うわ! gitは foo〜1をオリジン上の場所として解決し、それらのコミットをbar(ローカルブランチ)にダウンロードしました。宛先を指定したため、fooo/fooが更新されなかったことに注意してください。


What if the destination doesn't exist before I run the command? Let's see the last slide but without bar existing beforehand.

コマンドを実行する前に宛先が存在しない場合はどうなると思いますか?最後のスライドを見てみましょう。事前にbarは存在していません。

$ git fetch origin foo~1:bar

See, it's JUST like git push. Git made the destination locally before fetching, just like git will make the destination on remote before pushing (if it doesn't exist).

ほら、git pushにそっくりですね。gitがプッシュする前にリモートで宛先を作成するのと同じように、Gitはフェッチする前に宛先をローカルで作成します(存在しない場合)。

No args?
If git fetch receives no arguments, it just downloads all the commits from the remote onto all the remote branches...

引数がなければ?
リモートからすべてのリモートブランチにすべてのコミットをダウンロードするだけです...

$ git fetch

Pretty simple, but worth going over just once.

非常に単純ですが、一度だけやってみる価値はありそうです。

Ok, enough talking! To finish this level, fetch just the specified commits in the goal visualization. Get fancy with those commands!

話はここまで!このレベルを終了するには、ゴールの図で指定されたコミットのみをフェッチします。これらのコマンドを試してみてください!

You will have to specify the source and destination for both fetch commands. Pay attention to the goal visualization since the IDs may be switched around!

両方のフェッチコマンドの送信元と宛先を指定する必要があります。 IDが入れ替わる可能性があるため、ゴールの図に注意してください。


Gitリモート上級編 | 7: 無のsource

Oddities of <source> / <source>の奇妙さ

Git abuses the <source> parameter in two weird ways. These two abuses come from the fact that you can technically specify "nothing" as a valid source for both git push and git fetch. The way you specify nothing is via an empty argument:

Gitは2つの奇妙な方法で<source>パラメータを「悪用」します。これらの2つの悪用は、git pushとgit fetchの両方の有効なソースとして「無」を技術的に指定できるという事実に起因しています。何も指定しない方法は、空の引数を使用することです。

  • git push origin :side
  • git fetch origin :bugFix

Let's see what these do...

これらが何をするか見てみましょう...

What does pushing "nothing" to a remote branch do? It deletes it!

リモートブランチに「無」をプッシュするとどうなるか? 削除します!

$ git push origin :foo

There, we successfully deleted the foo branch on remote by pushing the concept of "nothing" to it. That kinda makes sense...

「無」という概念をプッシュすることで、リモートのfooブランチを正常に削除しました。ある意味合理的ですね…

Finally, fetching "nothing" to a place locally actually makes a new branch.

最後に、ローカルの場所に「無」をフェッチして、実際に新しいブランチを作成します。

$ git fetch origin :bar

Very odd / bizarre, but whatever. That's git for you!

とても奇妙で不可解ですよね…。いずれにせよ、あなたのためのgitです!

This is a quick level -- just delete one remote branch and create a new branch with git fetch to finish!

これは簡単なレベルです。1つのリモートブランチを削除し、git fetchを使用して新しいブランチを作成すれば終了です!


Gitリモート上級編 | 8: Pullの引数(最後のLevel)

Git pull arguments / pullの引数

Now that you know pretty much everything there is to know about arguments for git fetch and git push, there's almost really nothing left to cover for git pull :)

git fetchgit pushの引数について知っておくべきことはほぼすべてわかったので、git pullについてカバーすることはほとんどありません :)

That's because git pull at the end of the day is really just shorthand for a fetch followed by merging in whatever was just fetched. You can think of it as running git fetch with the same arguments specified and then merging in where those commits ended up.

というのも、git pullは結局のところ「フェッチしたものをマージしているだけ」です。同じ引数でgit fetchを実行し、それらのコミットをマージすると考えることができます。

This applies even when you use crazy-complicated arguments as well. Let's see some examples:

これは、非常に複雑な引数を使用する場合も同様です。いくつかの例を見てみましょう:

Here are some equivalent commands in git:

同等のコマンドを幾つか紹介します。

$ git pull origin foo

$ git fetch origin foo
$ git merge o/foo

# 1つ目のコマンドと、2つ目+3つ目のコマンドは一緒です

And...

そして、

$ git pull origin bar~1:bugFix

$ git fetch origin bar~1:bugFix
$ git merge bugFix

# こちらも1つ目のコマンドと、2つ目+3つ目のコマンドは一緒です

See? git pull is really just shorthand for fetch + merge, and all git pull cares about is where the commits ended up (the destination argument that it figures out during fetch).

Lets see a demo:

ね? git pullは単なるfetch + mergeの省略形で、git pullで気にするのはコミットが終了した場所なのです(フェッチの際に把握する宛先の引数)。

デモを見てみましょう:

If we specify the place to fetch, everything happens as before with fetch but we merge in whatever was just fetched.

場所を指定すると、以前と同じようにすべてフェッチで行われますが、フェッチしたものをマージします。

$ git pull origin master

See! by specifying master we downloaded commits onto o/master just as normal. Then we merged o/master to our currently checked out location which is not the local branch master.

masterを指定することで通常どおりo/masterにコミットをダウンロードしました! そして、o/masterを、ローカルブランチの masterではなく現在チェックアウトしている場所にマージしました。

For this reason it can actually make sense to run git pull multiple times (with the same args) from different locations in order to update multiple branches.

このため、複数のブランチを更新するために、異なる場所からgit pullを複数回(同じ引数で)実行することは、実際には理にかなっています。

Does it work with source and destination too? You bet! Let's see that:

<sourse>:<destination>も機能するのでしょうか? もちろん! 実際に見てみましょう:

$ git pull origin master:foo

Wow, that's a TON in one command. We created a new branch locally named foo, downloaded commits from remote's master onto that branch foo, and then merged that branch into our currently checked out branch bar. It's over 9000!!!

おぉ、1つのコマンドでものすごいことが。ローカルでfooという名前の新しいブランチを作成し、リモートのmasterからfooブランチにコミットをダウンロードし、そしてそのブランチを現在チェックアウトしているbarブランチにマージしました。すごすぎる!

訳註:
「It's over 9000!!!」はドラゴンボールに出てくるベジータの台詞(悟空の信じられない戦闘力を目の当たりにしてスカウターを握り潰しながら言った台詞)が元ネタで、調べたところ英語圏では「とてつもない量や力」を表現するときに用いられているようでした。
ちなみに原作の台詞は「8000以上だ…!」なのですが、英語吹替版のアニメでなぜか「It's over 9000!」と翻訳され、そのシーンがYouTubeを中心に広まっていったそうです😅
(参考 : It's Over 9000! - Wikipedia


Ok to finish up, attain the state of the goal visualization. You'll need to download some commits, make some new branches, and merge those branches into other branches, but it shouldn't take many commands :P

最後の仕上げとしてゴールに到達してください。いくつかのコミットをダウンロードし、いくつかの新しいブランチを作成し、それらのブランチを他のブランチにマージする必要はありますが、多くのコマンドを実行する必要はありませんよ :P


以上、最後までお読みいただきありがとうございました!