From 45ccb0e2ed065ddaadca1d8f02e87ab8f5cc3bd3 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Tue, 10 Dec 2013 15:34:47 -0800 Subject: [PATCH 01/47] Readme for Pull #150 Issue #150 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b10ba8ae..bb02b2f4 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ Also huge shoutout for everyone who has put up a pull request that was pulled: * Max Sikström (pengi) [tag support!!] * "rogererens" * Emanuel Schorsch +* Carl X. Su Or reported an issue that was successfully closed! From fcd0ffce855c59089179184b6657e8a04071977c Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 15 Dec 2013 17:23:51 -0800 Subject: [PATCH 02/47] Resolves Issue #151 silly assert issue --- src/js/git/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/git/commands.js b/src/js/git/commands.js index c2676020..975bfbd3 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -48,7 +48,7 @@ var assertNotCheckedOut = function(engine, ref) { var assertIsBranch = function(engine, ref) { assertIsRef(engine, ref); var obj = engine.refs[ref]; - if (obj.get('type') !== 'branch') { + if (!obj || obj.get('type') !== 'branch') { throw new GitError({ msg: intl.todo( ref + ' is not a branch' From 4c350da546f18a9a14082143c8f601974d2cbe96 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 15 Dec 2013 17:25:30 -0800 Subject: [PATCH 03/47] Test for Issue #151 --- spec/remote.spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/remote.spec.js b/spec/remote.spec.js index 101707cf..e614e16a 100644 --- a/spec/remote.spec.js +++ b/spec/remote.spec.js @@ -346,5 +346,12 @@ describe('Git Remotes', function() { ); }); + it('does not fetch if one arg is not branch ref', function() { + expectTreeAsync( + 'git clone; git fakeTeamwork 2; git fetch origin master~1', + '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C3","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C2"],"id":"C3"}},"tags":{},"HEAD":{"target":"master","id":"HEAD"}}}' + ); + }); + }); From f7a6acd4940c7e7ec089fc484d93d779649ee932 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Wed, 18 Dec 2013 16:33:45 +0100 Subject: [PATCH 04/47] Added locale german, lots of translations --- src/js/dialogs/confirmShowSolution.js | 10 +++ src/js/dialogs/levelBuilder.js | 20 ++++++ src/js/dialogs/nextLevel.js | 11 +++ src/js/dialogs/sandbox.js | 56 ++++++++++++++++ src/js/intl/strings.js | 97 +++++++++++++++++++++++++-- src/js/views/index.js | 8 +++ 6 files changed, 195 insertions(+), 7 deletions(-) diff --git a/src/js/dialogs/confirmShowSolution.js b/src/js/dialogs/confirmShowSolution.js index 86ec1636..377847bd 100644 --- a/src/js/dialogs/confirmShowSolution.js +++ b/src/js/dialogs/confirmShowSolution.js @@ -9,6 +9,16 @@ exports.dialog = { ] } }], + 'de_DE': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Bist du sicher, dass du die Auflösung sehen willst?', + '', + 'Ich glaube an dich! Du schaffst das!' + ] + } + }], 'zh_CN': [{ type: 'ModalAlert', options: { diff --git a/src/js/dialogs/levelBuilder.js b/src/js/dialogs/levelBuilder.js index a597756c..e37d36de 100644 --- a/src/js/dialogs/levelBuilder.js +++ b/src/js/dialogs/levelBuilder.js @@ -18,6 +18,26 @@ exports.dialog = { ] } }], + 'de_DE': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Willkommen zum Level-Editor!', + '', + 'So funktioniert\'s:', + '', + ' * Stelle mit git-Kommandos die Ausganssituation her', + ' * Leg den Startpunkt mit ```define start``` fest', + ' * Gib eine Abfolge von git-Kommandos ein, welche die (optimale) Lösung darstellen', + ' * Leg den Ziel-Baum mit ```define goal``` fest. Damit markierst du den Endpunkt der Lösung', + ' * Optionally define a hint with ```define hint```', + ' * Gib einen Hinweis mittels ```define hint``` an, wenn du willst', + ' * Änder den Namen mittels ```define name```', + ' * Wenn du magst, erstelle einen schönene Einführungsdialog mit ```edit dialog```', + ' * Gib das Kommando ```finish``` ein um deinen Level als JSON auszugeben!' + ] + } + }], 'zh_CN': [{ type: 'ModalAlert', options: { diff --git a/src/js/dialogs/nextLevel.js b/src/js/dialogs/nextLevel.js index c6e3cf75..4a398183 100644 --- a/src/js/dialogs/nextLevel.js +++ b/src/js/dialogs/nextLevel.js @@ -10,6 +10,17 @@ exports.dialog = { ] } }], + 'en_US': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Super gemacht!', + '', + 'Du hast den level in *{numCommands}* command(s) gelöst;', + 'unsere Lösung braucht {best}.' + ] + } + }], 'ja': [{ type: 'ModalAlert', options: { diff --git a/src/js/dialogs/sandbox.js b/src/js/dialogs/sandbox.js index e745d8d9..d854a3e6 100644 --- a/src/js/dialogs/sandbox.js +++ b/src/js/dialogs/sandbox.js @@ -55,6 +55,62 @@ exports.dialog = { ] } }], + 'de_DE': [{ + type: 'ModalAlert', + options: { + markdowns: [ + '## Willkommen bei LearnGitBranching!', + '', + 'Diese Anwendung wurde geschrieben um die umfangreichen', + 'Zusammenhänge beim Arbeiten mit Branches in git zu', + 'verdeutlichen. Wir hoffen du hast Spaß und lernst', + 'vielleicht sogar etwas dabei!', + '', + '# Demo!', + '', + 'Falls du die Demonstration noch nicht gesehen hast, schau sie dir hier an:', + '', + '[http://pcottle.github.io/learnGitBranching/?demo](http://pcottle.github.io/learnGitBranching/?demo)', + '', + 'Genervt von diesem Fenster? Häng `?NODEM` an die url um es los zu werden, siehe unten:', + '', + '[http://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Git-Kommandos', + '', + 'Dir steht eine große Zahl von git-Kommandos im Sandkasten-Modus zur Verfügung. Unter anderem', + '', + ' * commit', + ' * branch', + ' * checkout', + ' * cherry-pick', + ' * reset', + ' * revert', + ' * rebase', + ' * merge' + ] + } + }, { + type: 'ModalAlert', + options: { + markdowns: [ + '## Teilen macht Spaß!', + '', + 'Teile diese git-Bäume mit deinen Freunden mittels `export tree` und `import tree`', + '', + 'Hast du Wissenswertes zu git zu vermitteln? Versuch einen Level mit `build level` zu bauen oder probier den Level eines Freundes mit `import level` aus', + '', + 'Um alle Kommandos zu sehen, gib `show commands` ein. Darunter gibt\'s kleine Schätze wie `undo` und `reset`', + '', + 'Für\'s Erste lass uns mit `levels` anfangen ...' + ] + } + }], 'ja': [{ type: 'ModalAlert', options: { diff --git a/src/js/intl/strings.js b/src/js/intl/strings.js index b8f2a9ab..6f418777 100644 --- a/src/js/intl/strings.js +++ b/src/js/intl/strings.js @@ -4,6 +4,7 @@ exports.strings = { '__desc__': 'One of the lines in the next level dialog', 'ja': '最後のレベルをクリアしました!すごい!!', 'en_US': 'Wow! You finished the last level, great!', + 'de_DE': 'Wow! Du hast den letzten Level gelöst, super!', 'zh_CN': '我的个天!你完成了最后一关,碉堡了!', 'fr_FR': 'Félicitations, vous avez réussi le dernier niveau !' }, @@ -11,6 +12,7 @@ exports.strings = { 'finish-dialog-next': { '__desc__': 'One of the lines in the next level dialog', 'en_US': 'Would you like to move on to *"{nextLevel}"*, the next level?', + 'de_DE': 'Möchtest du mit *"{nextLevel}"* weitermachen, dem nächsten Level?', 'ja': '次の章 *"{nextLevel}"* へ進みますか?', 'zh_CN': '要不前进到下一关 *“{nextLevel}”*?', 'fr_FR': 'Voulez-vous passer à *"{nextLevel}"*, le prochain niveau ?' @@ -19,6 +21,7 @@ exports.strings = { 'finish-dialog-win': { '__desc__': 'One of the lines in the next level dialog', 'en_US': 'Awesome! You matched or exceeded our solution.', + 'de_DE': 'Wahnsinn! Du warst so gut wie unsere Lösung, oder sogar besser.', 'ja': '素晴らしい!このレベルをクリアしましたね。', 'zh_CN': '牛鼻啊!你达到或者完爆了我们的答案。', 'fr_FR': 'Fabuleux ! Votre solution a égalé ou surpassé notre solution.' @@ -27,6 +30,7 @@ exports.strings = { 'finish-dialog-lose': { '__desc__': 'When the user entered more commands than our best, encourage them to do better', 'en_US': 'See if you can whittle it down to {best} :D', + 'de_DE': 'Schau mal ob du es in {best} Schritten hinbekommst :D', 'ja': '模範解答の回数={best}回でクリアする方法も考えてみましょう :D', 'zh_CN': '试试看你能否在 {best} 之内搞定 :D', 'fr_FR': 'Voyons si vous pouvez descendre à {best} :D' @@ -34,32 +38,38 @@ exports.strings = { /////////////////////////////////////////////////////////////////////////// 'hg-prune-tree': { '__desc__': 'warning when pruning tree', - 'en_US': 'Warning! Mercurial does aggressive garbage collection and thus needs to prune your tree' + 'en_US': 'Warning! Mercurial does aggressive garbage collection and thus needs to prune your tree', + 'de_DE': 'Achtung! Mercurial macht aggressive Garbage Collection und muss daher deinen Baum reduzieren' }, /////////////////////////////////////////////////////////////////////////// 'hg-a-option': { '__desc__': 'warning for when using -A option', - 'en_US': 'The -A option is not needed for this app, just commit away!' + 'en_US': 'The -A option is not needed for this app, just commit away!', + 'de_DE': 'Die Option -A wird in dieser Anwendung nicht benötigt, committe einfach!' }, /////////////////////////////////////////////////////////////////////////// 'hg-error-no-status': { '__desc__': 'One of the errors for hg', - 'en_US': 'There is no status command for this app, since there is no staging of files. Try hg summary instead' + 'en_US': 'There is no status command for this app, since there is no staging of files. Try hg summary instead', + 'de_DE': 'Es gibt keinen Befehl status in dieser Anwendung, da es kein Staging von Dateien gibt. Probier stattdessen hg summary' }, /////////////////////////////////////////////////////////////////////////// 'hg-error-need-option': { '__desc__': 'One of the errors for hg', - 'en_US': 'I need the option {option} for that command!' + 'en_US': 'I need the option {option} for that command!', + 'de_DE': 'Ich benötige die Option {option} für diesen Befehl!' }, /////////////////////////////////////////////////////////////////////////// 'hg-error-log-no-follow': { '__desc__': 'hg log without -f (--follow)', - 'en_US': 'hg log without -f is currently not supported, use -f' + 'en_US': 'hg log without -f is currently not supported, use -f', + 'de_DE': 'hg log ohne -f wird aktuell nicht unterstützt, benutze bitte -f' }, /////////////////////////////////////////////////////////////////////////// 'git-status-detached': { '__desc__': 'One of the lines for git status output', 'en_US': 'Detached head!', + 'de_DE': 'Detached head!', 'zh_CN': '脑袋搬家(Detached head)了!', 'fr_FR': 'head détaché !' }, @@ -67,6 +77,7 @@ exports.strings = { 'git-status-onbranch': { '__desc__': 'One of the lines for git status output', 'en_US': 'On branch {branch}', + 'de_DE': 'Auf Branch {branch}', 'zh_CN': '切换到分支 {branch}', 'fr_FR': 'Sur la branche {branch}' }, @@ -74,6 +85,7 @@ exports.strings = { 'git-status-readytocommit': { '__desc__': 'One of the lines for git status output', 'en_US': 'Ready to commit! (as always in this demo)', + 'de_DE': 'Fertig zum committen! (Wie immer in dieser Demo)', 'zh_CN': '可以提交啦!(这演示里一直可以提交)', 'fr_FR': 'Prêt à commit ! (comme toujours dans cette démo)' }, @@ -82,37 +94,44 @@ exports.strings = { '__desc__': 'The dummy commit message for all commits. Feel free to put in a ' + 'shoutout to your school / city / whatever!', 'en_US': 'Quick commit. Go Bears!', + 'de_DE': 'Schneller Commit. Eff-Zeh!', 'zh_CN': '快速提交。上啊月熊!', 'fr_FR': 'Commit rapide. NoMaN Sux!' }, 'git-error-origin-fetch-uptodate': { '__desc__': 'One of the error messages for git', 'en_US': 'Already up to date!', + 'de_DE': 'Bereits aktuell!', 'fr_FR': 'Déjà à jour' }, 'git-error-origin-fetch-no-ff': { '__desc__': 'One of the error messages for git', 'en_US': 'Your origin branch is out of sync with the remote branch and fetch cannot be performed', + 'de_DE': 'Dein origin Branch ist nicht auf dem Stand des Remote Branch und fetch kann nicht ausgeführt werden', 'fr_FR': 'Votre branche origin n\'est plus synchronisée avec la branche distante et fetch ne peut pas être appliqué. Essayez avec l\'option --force' }, 'git-error-origin-push-no-ff': { '__desc__': 'One of the error messages for git', 'en_US': 'The remote repository has diverged from your local repository, so uploading your changes is not a simple fast forward (and thus your push was rejected). Please pull down the new changes in the remote repository, incorporate them into this branch, and try again. You can do so with git pull or git pull --rebase', + 'de_DE': 'Das entfernte Repository weicht von deinem lokalen Repository ab, daher können deine Änderungen nicht mit einem einfachen fast forward hochgeladen werden (und daher ist dein push abgelehnt worden). Bitte pull erst die neuen Änderungen in das lokale Repository, integriere sie in den Branch und versuch es nochmal. Das kannst du mit git pull oder git pull --rebase machen', 'fr_FR': 'Le dépôt distant a divergé de votre référentiel local, donc l\'envoi de vos modifications n\'est pas en simple avance rapide (et donc votre envoi a été rejeté). Veuillez récupérer les nouveaux changements depuis le dépôt distant, les intégrer dans cette branche, et essayez à nouveau. Vous pouvez le faire avec git pull ou git pull --rebase' }, 'git-error-remote-branch': { '__desc__': 'One of the error messages for git', 'en_US': 'You cannot execute that command on a remote branch', + 'de_DE': 'Du kannst diesen Befehl nicht auf einem Remote Branch ausführen', 'fr_FR': 'Vous ne pouvez exécuter cette commande sur une branche distante' }, 'git-error-origin-required': { '__desc__': 'One of the error messages for git', 'en_US': 'An origin is required for that command', + 'de_DE': 'Für diesen Befehl wird origin benötigt', 'fr_FR': 'Une origine est requise pour cette commande' }, 'git-error-origin-exists': { '__desc__': 'One of the error messages for git', 'en_US': 'An origin already exists! You cannot make a new one', + 'de_DE': 'origin existiert bereits! Du kannst es nicht nochmal anlegen', 'fr_FR': 'Une origine existe déjà ! Vous ne pouvez pas en créer une nouvelle' }, /////////////////////////////////////////////////////////////////////////// @@ -120,6 +139,7 @@ exports.strings = { '__desc__': 'One of the error messages for git', 'en_US': 'You can\'t delete the master branch, the branch you are on, or things that ' + 'aren\'t branches', + 'de_DE': 'Du kannst nicht den Branch master, den Branch auf dem du gerade arbeitest oder Refs, die keine Branches sind, löschen', 'zh_CN': '你不能删除主分支(master),或者你当前所在的分支,或者其他不是分支也不知道能不能吃的东西。', 'fr_FR': 'Vous ne pouvez supprimer la branche master, la branche sur laquelle vous êtes, ou ce qui n\'est pas une branche' }, @@ -127,6 +147,7 @@ exports.strings = { 'git-merge-msg': { '__desc__': 'The commit message for a merge commit', 'en_US': 'Merge {target} into {current}', + 'de_DE': 'Mergen von {target} in {current}', 'zh_CN': '合并 {target} 到 {current}', 'fr_FR': 'Merge de {target} dans {current}' }, @@ -134,6 +155,7 @@ exports.strings = { 'git-error-rebase-none': { '__desc__': 'One of the error messages for git', 'en_US': 'No commits to rebase! Everything is a merge commit or changes already applied', + 'de_DE': 'Keine Commits für Rebase gefunden! Alle Commits sind Merge Commits oder beinhalten nur schon vorhandene Änderungen', 'zh_CN': '没有需要 rebase 的提交!都是个合并提交,或者已经 rebase 过了。', 'fr_FR': 'Aucune commit à rebaser ! Tout est soit un commit de merge, soit des modifications déjà appliquées' }, @@ -141,6 +163,7 @@ exports.strings = { 'git-result-nothing': { '__desc__': 'The message that explains the result of a git command', 'en_US': 'Nothing to do...', + 'de_DE': 'Nichts zu tun ...', 'zh_CN': '没啥鸟事……', 'fr_FR': 'Rien à effectuer…' }, @@ -148,6 +171,7 @@ exports.strings = { 'git-result-fastforward': { '__desc__': 'The message that explains the result of a git command', 'en_US': 'Fast forwarding...', + 'de_DE': 'Fast forward...', 'zh_CN': '快速前进……', 'fr_FR': 'En avance rapide…' }, @@ -155,6 +179,7 @@ exports.strings = { 'git-result-uptodate': { '__desc__': 'The message that explains the result of a git command', 'en_US': 'Branch already up-to-date', + 'de_DE': 'Branch ist bereits aktuell', 'zh_CN': '分支已经是最新啦', 'fr_FR': 'Branche déjà à jour' }, @@ -162,6 +187,7 @@ exports.strings = { 'git-error-exist': { '__desc__': 'One of the error messages for git', 'en_US': 'The ref {ref} does not exist or is unknown', + 'de_DE': 'Die Ref {ref} existiert nicht oder ist unbekannt', 'zh_CN': '索引 {ref} 不存在,或者找不到。', 'fr_FR': 'La référence {ref} n\'existe pas ou est inconnue' }, @@ -169,6 +195,7 @@ exports.strings = { 'git-error-relative-ref': { '__desc__': 'One of the error messages for git', 'en_US': 'Commit {commit} doesnot have a {match}', + 'de_DE': 'Commit {commit} hat kein {match}', 'zh_CN': '提交 {commit} 并没有 {match}', 'fr_FR': 'Le commit {commit} n\'a pas de correspondance {match}' }, @@ -176,6 +203,7 @@ exports.strings = { 'git-warning-detached': { '__desc__': 'One of the warning messages for git', 'en_US': 'Warning!! Detached HEAD state', + 'de_DE': 'Achtung! Detached HEAD Zustand', 'zh_CN': '警告!脑袋搬家(Detached HEAD)状态', 'fr_FR': 'Attention ! HEAD est détaché' }, @@ -183,6 +211,7 @@ exports.strings = { 'git-warning-add': { '__desc__': 'One of the warning messages for git', 'en_US': 'No need to add files in this demo', + 'de_DE': 'In dieser Demo müssen keine Dateien hinzugefügt werden', 'zh_CN': '此演示中不需要添加文件', 'fr_FR': 'Aucun besoin d\'ajouter des fichiers dans cette démo' }, @@ -190,6 +219,7 @@ exports.strings = { 'git-error-options': { '__desc__': 'One of the error messages for git', 'en_US': 'Those options you specified are incompatible or incorrect', + 'de_DE': 'Die angegebenen Optionen sind inkompatibel oder falsch', 'zh_CN': '你所指定的参数不兼容或者不准确', 'fr_FR': 'Les options que vous avez spécifiées sont incompatibles ou incorrectes' }, @@ -197,6 +227,7 @@ exports.strings = { 'git-error-already-exists': { '__desc__': 'One of the error messages for git', 'en_US': 'The commit {commit} already exists in your changes set, aborting!', + 'de_DE': 'Der Commit {commit} existiert bereit, Abbruch!', 'zh_CN': '提交 {commit} 已经存在于你的改动集里,正在中止!', 'fr_FR': 'Le commit {commit} existe déjà dans votre ensemble de modifications, opération avortée !' }, @@ -204,6 +235,7 @@ exports.strings = { 'git-error-reset-detached': { '__desc__': 'One of the error messages for git', 'en_US': 'Can\'t reset in detached head! Use checkout if you want to move', + 'de_DE': 'Kann im Detached Head Zustand kein reset ausführen! Bitte checkout zum Bewegen benutzen', 'zh_CN': '不能在分离的 HEAD 里重置!用 checkout 吧', 'fr_FR': 'On ne peut pas effectuer un reset quand head est détaché. Utilisez checkout pour déplacer' }, @@ -211,6 +243,7 @@ exports.strings = { 'git-warning-hard': { '__desc__': 'One of the warning messages for git', 'en_US': 'The default behavior is a --hard reset, feel free to omit that option!', + 'de_DE': 'Das Standardverhalten in dieser Demo ist --hard, du kannst die Option auch weglassen!', 'zh_CN': '默认的行为是 --hard 硬重置,尽管省略掉那个选项吧!', 'fr_FR': 'Le comportement par défaut est un --hard reset, soyez libre d\'omettre cette option !' }, @@ -219,6 +252,7 @@ exports.strings = { '__desc__': 'One of the error messages for git', 'en_US': 'There is no concept of adding / staging files, so that option or ' + 'command is invalid!', + 'de_DE': 'In dieser Demo gibt es kein Hinzufügen / Vormerken von Dateien, dieser Befehl ist daher ungültig!', 'zh_CN': '没有添加、缓存文件的必要,所以改选项或者命令是不合法的。', 'fr_FR': 'Il n\'y a pas le concept d\'ajouter / mettre en staging, donc cette option ou commande est invalide' }, @@ -226,6 +260,7 @@ exports.strings = { 'git-revert-msg': { '__desc__': 'Message for reverting git command', 'en_US': 'Reverting {oldCommit}: {oldMsg}', + 'de_DE': 'Reverte {oldCommit}: {oldMsg}', 'zh_CN': '撤销 {oldCommit}:{oldMsg}', 'fr_FR': 'Revert {oldCommit}: {oldMsg}' }, @@ -233,6 +268,7 @@ exports.strings = { 'git-error-args-many': { '__desc__': 'One of the error messages for git', 'en_US': 'I expect at most {upper} argument(s) for {what}', + 'de_DE': 'Ich benötige maximal {upper} Argumente für {what}', 'zh_CN': '{what} 期望最多 {upper} 个参数', 'fr_FR': 'J\'attends au plus {upper} argument(s) pour {what}' }, @@ -240,6 +276,7 @@ exports.strings = { 'git-error-args-few': { '__desc__': 'One of the error messages for git', 'en_US': 'I expect at least {lower} argument(s) for {what}', + 'de_DE': 'Ich benötige höchstens {lower} Argumente für {what}', 'zh_CN': '{what} 期望最少 {lower} 个参数', 'fr_FR': 'J\'attends au moins {upper} argument(s) pour {what}' }, @@ -247,6 +284,7 @@ exports.strings = { 'git-error-no-general-args': { '__desc__': 'One of the error messages for git', 'en_US': 'That command accepts no general arguments', + 'de_DE': 'Dieser Befehl akzeptiert keine allgemeinen Argumente', 'zh_CN': '该命令不接收参数', 'fr_FR': 'Cette commande n\'accepte aucun argument général' }, @@ -254,6 +292,7 @@ exports.strings = { 'copy-tree-string': { '__desc__': 'The prompt to copy the tree when sharing', 'en_US': 'Copy the tree string below', + 'de_DE': 'Kopiere die folgende Baum-Zeichenkette', 'zh_CN': '拷贝下面的树字符串', 'fr_FR': 'Copiez la chaîne d\'arbre ci-dessous' }, @@ -261,6 +300,7 @@ exports.strings = { 'learn-git-branching': { '__desc__': 'The title of the app, with spaces', 'en_US': 'Learn Git Branching', + 'de_DE': 'Learn Git Branching', 'ja': '日本語版リポジトリ', 'ko': 'Git 브랜치 배우기', 'zh_CN': '学习Git分支', @@ -270,6 +310,7 @@ exports.strings = { 'select-a-level': { '__desc__': 'The prompt to select a level on the drop down view', 'en_US': 'Select a level', + 'de_DE': 'Level auswählen', 'zh_CN': '选择一关', 'fr_FR': 'Choisissez un niveau' }, @@ -277,6 +318,7 @@ exports.strings = { 'branch-name-short': { '__desc__': 'When branch names get too long, we need to truncate them. This is the warning for that', 'en_US': 'Sorry, we need to keep branch names short for the visuals. Your branch name was truncated to 9 characters, resulting in "{branch}"', + 'de_DE': 'Tut mir leid, aber aus Gründen der Darstellung müssen wir die Branch-Namen kurz halten. Dein Branch-Name wurde auf 9 Zeichen gekürzt und heißt daher jetzt "{branch}"', 'zh_CN': '抱歉,为了显示的需要,我们需要一个短些的分支名称。您使用的将被截断到9个字符,即"{branch}"', 'fr_FR': 'Désolé, nous devons garder les noms de branches courts pour la visualisation. Votre nom de branche a été tronqué à 9 caractères, devenant "{branch}"' }, @@ -284,18 +326,21 @@ exports.strings = { 'bad-branch-name': { '__desc__': 'When the user enters a branch name thats not ok', 'en_US': 'That branch name "{branch}" is not allowed!', + 'de_DE': 'Der Branch-Name "{branch}" ist nicht erlaubt!', 'zh_CN': '不能给分支起这个名字 "{branch}"', 'fr_FR': 'Ce nom de branche "{branch}" n\'est pas autorisé' }, /////////////////////////////////////////////////////////////////////////// 'bad-tag-name': { '__desc__': 'When the user enters a tag name thats not ok', - 'en_US': 'That tag name "{tag}" is not allowed!' + 'en_US': 'That tag name "{tag}" is not allowed!', + 'de_DE': 'Der Tag-Name "{tag}" ist nicht erlaubt!' }, /////////////////////////////////////////////////////////////////////////// 'option-not-supported': { '__desc__': 'When the user specifies an option that is not supported by our demo', 'en_US': 'The option "{option}" is not supported!', + 'de_DE': 'Die Option "{option}" wird nicht unterstützt!', 'zh_CN': '不支持选项 "{option}"', 'fr_FR': 'L\'option "{option}" n\'est pas supportée' }, @@ -303,6 +348,7 @@ exports.strings = { 'git-usage-command': { '__desc__': 'The line that shows how to format a git command', 'en_US': 'git []', + 'de_DE': 'git []', 'zh_CN': 'git <命令> [<参数>]', 'fr_FR': 'git []' }, @@ -310,6 +356,7 @@ exports.strings = { 'git-supported-commands': { '__desc__': 'In the git help command, the header above the supported commands', 'en_US': 'Supported commands:', + 'de_DE': 'Unterstützte Befehle:', 'zh_CN': '支持的命令有:', 'fr_FR': 'Commandes supportées' }, @@ -317,6 +364,7 @@ exports.strings = { 'git-usage': { '__desc__': 'In the dummy git output, the header before showing all the commands', 'en_US': 'Usage:', + 'de_DE': 'Benutzung:', 'zh_CN': '使用:', 'fr_FR': 'Utilisation :' }, @@ -324,6 +372,7 @@ exports.strings = { 'git-version': { '__desc__': 'The git version dummy output, kind of silly. PCOTTLE is my unix name but feel free to put yours instead', 'en_US': 'Git Version PCOTTLE.1.0', + 'de_DE': 'Git Version PCOTTLE.1.0.jbr', 'zh_CN': 'Git 版本 PCOTTLE.1.0', 'fr_FR': 'Git version PCOTTLE.1.0' }, @@ -331,6 +380,7 @@ exports.strings = { 'refresh-tree-command': { '__desc__': 'when the tree is visually refreshed', 'en_US': 'Refreshing tree...', + 'de_DE': 'Aktualisiere Baum ...', 'zh_CN': '正在刷新树结构...', 'fr_FR': 'Actualisation de l\'arbre…' }, @@ -338,6 +388,7 @@ exports.strings = { 'locale-command': { '__desc__': 'when the locale is set to something', 'en_US': 'Locale set to {locale}', + 'de_DE': 'Locale auf {locale} gesetzt', 'zh_CN': '语言更改为 {locale}', 'fr_FR': 'Langue changée à {locale}' }, @@ -345,6 +396,7 @@ exports.strings = { 'locale-reset-command': { '__desc__': 'when the locale is reset', 'en_US': 'Locale reset to default, which is {locale}', + 'de_DE': 'Locale auf Standard zurückgesetzt, also {locale}', 'zh_CN': '语言重置为默认的 {locale}', 'fr_FR': 'Langue remise par défaut, qui est {locale}' }, @@ -352,18 +404,21 @@ exports.strings = { 'show-command': { '__desc__': 'command output title from "show"', 'en_US': 'Please use one of the following commands for more info:', + 'de_DE': 'Bitte benutze einen der folgenden Befehle um mehr Informationen zu bekommen:', 'fr_FR': 'Merci d\'utiliser une des commandes suivantes pour obtenir plus d\'info' }, /////////////////////////////////////////////////////////////////////////// 'show-all-commands': { '__desc__': 'command output title from "show commands"', 'en_US': 'Here is a list of all the commmands available:', + 'de_DE': 'Hier ist eine Liste aller verfügbarer Befehle:', 'fr_FR': 'Ci-dessous est la liste de toutes les commandes disponibles :' }, /////////////////////////////////////////////////////////////////////////// 'cd-command': { '__desc__': 'dummy command output for the command in the key', 'en_US': 'Directory changed to "/directories/dont/matter/in/this/demo"', + 'de_DE': 'Verzeichnis gewechselt zu "/verzeichnisse/sind/in/dieser/demo/latte"', 'zh_CN': '目录切换到 "/directories/dont/matter/in/this/demo"', 'fr_FR': 'Répertoire changé à "/directories/dont/matter/in/this/demo" (les répertoires ne servent à rien dans cette démo)' }, @@ -371,12 +426,14 @@ exports.strings = { 'ls-command': { '__desc__': 'Dummy command output for the command in the key', 'en_US': 'DontWorryAboutFilesInThisDemo.txt', + 'de_DE': 'VergissDateienInDieserDemo.txt', 'zh_CN': 'DontWorryAboutFilesInThisDemo.txt (译: 在试验里不用担心文件.txt)', 'fr_FR': 'DontWorryAboutFilesInThisDemo.txt (ne vous préoccupez pas des noms de fichier dans cette démo)' }, 'mobile-alert': { '__desc__': 'When someone comes to the site on a mobile device, they can not input commands so this is a nasty alert to tell them', 'en_US': 'LGB can\'t receive input on mobile, visit on desktop! it\'s worth it :D', + 'de_DE': 'LGB ist nicht mit mobilen Endgeräten kompatibel, nutz es vom Desktop! Es lohnt sich :D', 'zh_CN': '无法在移动设备/平板上调出键盘 :( 请试试桌面版 :D', 'fr_FR': 'Impossible de faire apparaître le clavier sur mobile / tablette :( Essayez de passer sur un ordinateur de bureau :D' }, @@ -384,6 +441,7 @@ exports.strings = { 'share-tree': { '__desc__': 'When you export a tree, we want you to share the tree with friends', 'en_US': 'Share this tree with friends! They can load it with "import tree"', + 'de_DE': 'Teile diesen git-Baum mit Freunden! Sie können ihn mit "import tree" laden', 'zh_CN': '与你的好友分享提交树!他们可以用 "import tree" 加载它', 'fr_FR': 'Partagez cet arbre avec vos amis ! Ils peuvent le charger avec "import tree"' }, @@ -391,6 +449,7 @@ exports.strings = { 'paste-json': { '__desc__': 'When you are importing a level or tree', 'en_US': 'Paste a JSON blob below!', + 'de_DE': 'Füg einen JSON-Blob unten ein!', 'zh_CN': '在下边粘贴一个JSON串', 'fr_FR': 'Collez un blob JSON ci-dessous !' }, @@ -398,6 +457,7 @@ exports.strings = { 'solved-map-reset': { '__desc__': 'When you reset the solved map to clear your solved history, in case someone else wants to use your browser', 'en_US': 'Solved map was reset, you are starting from a clean slate!', + 'de_DE': 'Gelöste Karte wurde zurückgesetzt, du fängst mit einem leeren Blatt an!', 'zh_CN': '解决列表已重置,您现在从零开始了', 'fr_FR': 'La carte des niveaux résolus a été effacée, vous repartez de zéro !' }, @@ -405,6 +465,7 @@ exports.strings = { 'level-cant-exit': { '__desc__': 'When the user tries to exit a level when they are not in one', 'en_US': 'You are not in a level! You are in a sandbox, start a level with "levels"', + 'de_DE': 'Du bist nicht in einem Level! Du bist im Sandkasten-Modus, starte einen Level mit "levels"', 'zh_CN': '您没在关卡中!您在沙盒中,要开始关卡请输入 "levels"', 'fr_FR': 'Vous n\'êtes pas dans un niveau ! Vous êtes dans le mode bac à sable, commencez un niveau avec "levels"' }, @@ -412,6 +473,7 @@ exports.strings = { 'level-no-id': { '__desc__': 'When you say an id but that level doesnt exist', 'en_US': 'A level for that id "{id}" was not found! Opening up a level selection view', + 'de_DE': 'Konnte keinen Level mit der ID "{id}" finden! Öffne einen Level-Auswahldialog', 'zh_CN': '没找到id为 "{id}" 的关卡!打开关卡选择框', 'fr_FR': 'Le niveau dont l\'identifiant est {id} n\'a pas été trouvé ! Ouverture de la vue de sélection des niveaux' }, @@ -419,6 +481,7 @@ exports.strings = { 'undo-stack-empty': { '__desc__': 'The undo command can only undo back until the last time the level was reset or the beginning of the level', 'en_US': 'The undo stack is empty!', + 'de_DE': 'Die Undo-Liste ist leer!', 'zh_CN': '还没有什么可以撤销', 'fr_FR': 'La pile d\'annulation est vide !' }, @@ -426,6 +489,7 @@ exports.strings = { 'already-solved': { '__desc__': 'When you play in a level that is already solved', 'en_US': 'You have already solved this level, try other levels with "levels" or go back to sandbox with "sandbox"', + 'de_DE': 'Du hast diesen Level bereits gelöst, probier einen anderen Level mit "levels" aus oder geh in den Sandkasten-Modus mit "sandbox"', 'zh_CN': '你已经解决了本关,输入 "levels" 尝试其他关卡,或者输入 "sandbox" 回到沙盒中', 'fr_FR': 'Vous avez déjà résolu ce niveau, essayez d\'autres niveaux avec "levels" ou revenez au bac à sable avec "sandbox"' }, @@ -433,6 +497,7 @@ exports.strings = { 'command-disabled': { '__desc__': 'When you try a command that is disabled', 'en_US': 'That git command is disabled for this level!', + 'de_DE': 'Dieser git-Befehl ist für diesen Level deaktiviert!', 'zh_CN': '该命令在本关不允许使用!', 'fr_FR': 'Cette commande git est désactivée pour ce niveau !' }, @@ -440,6 +505,7 @@ exports.strings = { 'share-json': { '__desc__': 'when you have made the level, prompt to share this', 'en_US': 'Here is the JSON for this level! Share it with somenoe or send it to me on Github', + 'de_DE': 'Hier ist das JSON für diesen Level! Teil es mit jemandem or schick es mir über Github', 'zh_CN': '这是一个关卡定义JSON!您可以分享它或者发到我的GitHub上', 'fr_FR': 'Voici le JSON pour ce niveau ! Partagez-le avec quelqu\'un ou envoyez-le moi sur Github' }, @@ -447,6 +513,7 @@ exports.strings = { 'want-start-dialog': { '__desc__': 'prompt to add a start dialog', 'en_US': 'You have not specified a start dialog, would you like to add one?', + 'de_DE': 'Du hast noch keinen Einführungs-Dialog geschrieben, willst du einen hinzufügen?', 'zh_CN': '您还没有定义一开始的介绍,是否添加一个?', 'fr_FR': 'Vous n\'avez pas spécifié de dialogue de départ, voulez-vous en ajouter un ?' }, @@ -454,6 +521,7 @@ exports.strings = { 'want-hint': { '__desc__': 'prompt to add a hint', 'en_US': 'You have not specified a hint, would you like to add one?', + 'de_DE': 'Du hast noch keinen Hinweis geschrieben, magst du einen hinzufügen?', 'zh_CN': '您还没有定义提示,是否添加一个?', 'fr_FR': 'Vous n\'avez pas spécifié d\'indice, voulez-vous en ajouter un ?' }, @@ -461,6 +529,7 @@ exports.strings = { 'prompt-hint': { '__desc__': 'prompt for hint', 'en_US': 'Enter the hint for this level, or leave this blank if you do not want to include one', + 'de_DE': 'Gib den Hinweis für diesen Level an, oder lass es leer wenn du keinen hinzufügen willst', 'zh_CN': '请输入关卡提示,或者故意留空', 'fr_FR': 'Entrez l\'indice pour ce niveau, ou laissez-le vide pour ne pas l\'inclure' }, @@ -468,6 +537,7 @@ exports.strings = { 'prompt-name': { '__desc__': 'prompt for level name', 'en_US': 'Enter the name for the level', + 'de_DE': 'Gib den Namen für diesen Level an', 'zh_CN': '输入关卡名', 'fr_FR': 'Entrez le nom pour ce niveau' }, @@ -475,6 +545,7 @@ exports.strings = { 'solution-empty': { '__desc__': 'If you define a solution without any commands, aka a level that is solved without doing anything', 'en_US': 'Your solution is empty!! Something is amiss', + 'de_DE': 'Deine Auflösung ist leer! Hier fehlt etwas', 'zh_CN': '你的解法是空的!! 这应该是出错了', 'fr_FR': 'Votre solution est vide !! Quelque chose ne tourne pas rond' }, @@ -482,6 +553,7 @@ exports.strings = { 'define-start-warning': { '__desc__': 'When you define the start point again, it overwrites the solution and goal so we add a warning', 'en_US': 'Defining start point... solution and goal will be overwritten if they were defined earlier', + 'de_DE': 'Lege Start fest ... Auflösung und Ziel werden gelößcht, falls sie schon festgelegt worden waren', 'zh_CN': '定义开始点... 解决方法和目标会被新的替代', 'fr_FR': 'Redéfinition du point de départ… la solution et la cible seront écrasés s\'ils ont déjà été définis' }, @@ -489,6 +561,7 @@ exports.strings = { 'help-vague-level': { '__desc__': 'When you are in a level and you say help, its vague and you need to specify', 'en_US': 'You are in a level, so multiple forms of help are available. Please select either "help level" to learn more about this lesson, "help general" for using Learn GitBranching, or "objective" to learn about how to solve the level.', + 'de_DE': 'Du befindest dich in einem Level, daher gibt es verschiedene Hilfen. Gib "help level" ein um mehr úber diesen Level zu erfahren, "help general" um zu sehen wie Learn Git Branching bedient wird, oder "objective" um das Ziel dieses Levels zu erfahren.', 'zh_CN': '您正在关卡中,这里有多种形式的帮助,请选择 "help level" (关卡帮助)或 "help general" (一般帮助)', 'fr_FR': 'Vous êtes dans un niveau, donc plusieurs formes d\'aide sont disponibles. Merci de sélectionner soit "help level" pour en apprendre plus sur cette leçon, "help general" pour l\'utilisation de Learn GitBranching, ou "objective" pour apprendre comment résoudre le niveau' }, @@ -496,6 +569,7 @@ exports.strings = { 'help-vague-builder': { '__desc__': 'When you are in a level builder, the help command is vague so you need to specify what you mean', 'en_US': 'You are in a level builder, so multiple forms of help are available. Please select either "help general" or "help builder"', + 'de_DE': 'Du befindest dich im Level-Editor, daher gibt es verschiedene Hilfen. Gib bitte "help general" oder "help builder" ein', 'zh_CN': '您正在进行关卡构建中,这里有多种形式的帮助,请选择 "help general" (一般帮助)或 "help builder" (关卡构建帮助)', 'fr_FR': 'Vous êtes dans l\'éditeur de niveaux, donc plusieurs formes d\'aide sont disponibles. Merci de sélectionner soit "help general" soit "help builder"' }, @@ -503,18 +577,21 @@ exports.strings = { 'goal-to-reach': { '__desc__': 'title of window that shoes the goal tree to reach', 'en_US': 'Goal To Reach', + 'de_DE': 'Ziel', 'zh_CN': '目标', 'fr_FR': 'Cible à atteindre' }, /////////////////////////////////////////////////////////////////////////// 'goal-only-master': { '__desc__': 'the helper message for the window that shows the goal tree when the goal will only be compared using the master branch', - 'en_US': 'Note: Only the master branch will be checked in this level. The other branches are simply for reference (shown as dashed labels below). As always, you can hide this dialog with "hide goal"' + 'en_US': 'Note: Only the master branch will be checked in this level. The other branches are simply for reference (shown as dashed labels below). As always, you can hide this dialog with "hide goal"', + 'de_DE': 'Hinweis: In diesem Level wird nur der Branch master geprüft. Die anderen Branches dienen nur als Vergleichsbasis (als gestrichelte Bezeichner dargestellt). Wie immer kannst du diese Meldung mit "hide goal" ausblenden' }, /////////////////////////////////////////////////////////////////////////// 'hide-goal': { '__desc__': 'the helper message for the window that shows the goal tree', 'en_US': 'You can hide this window with "hide goal"', + 'de_DE': 'Du kannst diese Meldung mit "hide goal" ausblenden', 'zh_CN': '你可以通过命令 "hide goal" 关闭这个窗口', 'fr_FR': 'Vous pouvez masquer cette fenêtre avec "hide goal"' }, @@ -522,6 +599,7 @@ exports.strings = { 'hide-start': { '__desc__': 'The helper message for the window that shows the start tree for a level', 'en_US': 'You can hide this window with "hide start"', + 'de_DE': 'Du kannst diese Meldung mit "hide start" ausblenden', 'zh_CN': '你可以通过命令 "hide start" 关闭这个窗口', 'fr_FR': 'Vous pouvez masquer cette fenêtre avec "hide start"' }, @@ -529,6 +607,7 @@ exports.strings = { 'level-builder': { '__desc__': 'The name for the environment where you build levels', 'en_US': 'Level Builder', + 'de_DE': 'Level-Editor', 'zh_CN': '关卡生成器', 'fr_FR': 'Éditeur de niveaux' }, @@ -536,6 +615,7 @@ exports.strings = { 'no-start-dialog': { '__desc__': 'when the user tries to open a start dialog for a level that does not have one', 'en_US': 'There is no start dialog to show for this level!', + 'de_DE': 'Es gibt keinen Einführungs-Dialog für diesen Level!', 'zh_CN': '介绍? 这关真没有!', 'fr_FR': 'Il n\'y a aucun dialogue de départ à afficher pour ce niveau !' }, @@ -543,6 +623,7 @@ exports.strings = { 'no-hint': { '__desc__': 'when no hint is available for a level', 'en_US': "Hmm, there doesn't seem to be a hint for this level :-/", + 'de_DE': "Hm, es gibt anscheinend keinen Hinweis für diesen Level :-/", 'zh_CN': "提示?嗯,这关真没有哎~ :-/", 'fr_FR': 'Hum, il ne semble pas y avoir d\'indice pour ce niveau :-/' }, @@ -550,6 +631,7 @@ exports.strings = { 'error-untranslated-key': { '__desc__': 'This error happens when we are trying to translate a specific key and the locale version is mission', 'en_US': 'The translation for {key} does not exist yet :( Please hop on github and offer up a translation!', + 'de_DE': 'Die Übersetzung für {key} existiert noch nicht :( Falls du eine hast, bitte teil sie mit auf Github mit!', 'zh_CN': '还没翻译 {key} :( 请在gitHub上贡献你的翻译!', 'fr_FR': 'La traduction pour {key} n\'existe pas encore :( Venez sur Github pour en offrir une !' }, @@ -557,6 +639,7 @@ exports.strings = { 'error-untranslated': { '__desc__': 'The general error when we encounter a dialog that is not translated', 'en_US': 'This dialog or text is not yet translated in your locale :( Hop on github to aid in translation!', + 'de_DE': 'Dieser Dialog oder Text ist noch nicht in deine Sprache übersetzt. :( Schau auf Github vorbei um bei der Übersetzung zu helfen!', 'zh_CN': '这段对话还没有被翻译成你的语言 :( 欢迎在gitHub上贡献你的翻译!', 'fr_FR': 'Ce message n\'a pas encore été traduit dans votre langue :( Venez sur Github aider à la traduction !' } diff --git a/src/js/views/index.js b/src/js/views/index.js index 23649dec..252ddd7a 100644 --- a/src/js/views/index.js +++ b/src/js/views/index.js @@ -680,6 +680,9 @@ var IntlHelperBar = HelperBar.extend({ }, { text: 'français', id: 'french' + }, { + text: 'Deutsch', + id: 'german' }, { icon: 'signout', id: 'exit' @@ -711,6 +714,11 @@ var IntlHelperBar = HelperBar.extend({ this.hide(); }, + onGermanClick: function() { + this.fireCommand('locale de_DE; levels'); + this.hide(); + }, + onChineseClick: function() { this.fireCommand('locale zh_CN; levels'); this.hide(); From bdb799da329f59779b6512a51f6e19e34bf7ccca Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Wed, 18 Dec 2013 21:12:51 +0100 Subject: [PATCH 05/47] More translations, fixed existing ones --- src/js/dialogs/levelBuilder.js | 7 +- src/js/dialogs/nextLevel.js | 8 +-- src/js/dialogs/sandbox.js | 10 +-- src/levels/advanced/multipleParents.js | 89 ++++++++++++++++++++++++++ src/levels/index.js | 22 +++++-- src/levels/intro/branching.js | 75 ++++++++++++++++++++++ src/levels/intro/commits.js | 44 +++++++++++++ src/levels/intro/merging.js | 71 ++++++++++++++++++++ src/levels/intro/rebasing.js | 69 ++++++++++++++++++++ 9 files changed, 378 insertions(+), 17 deletions(-) diff --git a/src/js/dialogs/levelBuilder.js b/src/js/dialogs/levelBuilder.js index e37d36de..f4bc7ac2 100644 --- a/src/js/dialogs/levelBuilder.js +++ b/src/js/dialogs/levelBuilder.js @@ -26,15 +26,14 @@ exports.dialog = { '', 'So funktioniert\'s:', '', - ' * Stelle mit git-Kommandos die Ausganssituation her', + ' * Stelle mit Git-Befehlen die Ausganssituation her', ' * Leg den Startpunkt mit ```define start``` fest', - ' * Gib eine Abfolge von git-Kommandos ein, welche die (optimale) Lösung darstellen', + ' * Gib eine Abfolge von Git-Befehlen ein, welche die (optimale) Lösung darstellen', ' * Leg den Ziel-Baum mit ```define goal``` fest. Damit markierst du den Endpunkt der Lösung', - ' * Optionally define a hint with ```define hint```', ' * Gib einen Hinweis mittels ```define hint``` an, wenn du willst', ' * Änder den Namen mittels ```define name```', ' * Wenn du magst, erstelle einen schönene Einführungsdialog mit ```edit dialog```', - ' * Gib das Kommando ```finish``` ein um deinen Level als JSON auszugeben!' + ' * Gib das Kommando ```finish``` ein um deinen Level als JSON auszugeben' ] } }], diff --git a/src/js/dialogs/nextLevel.js b/src/js/dialogs/nextLevel.js index 4a398183..f199c4b1 100644 --- a/src/js/dialogs/nextLevel.js +++ b/src/js/dialogs/nextLevel.js @@ -10,14 +10,14 @@ exports.dialog = { ] } }], - 'en_US': [{ + 'de_DE': [{ type: 'ModalAlert', options: { markdowns: [ - '## Super gemacht!', + '## Super gemacht', '', - 'Du hast den level in *{numCommands}* command(s) gelöst;', - 'unsere Lösung braucht {best}.' + 'Du hast den Level in *{numCommands}* Befehl(en) gelöst;', + 'meine Lösung besteht aus {best}.' ] } }], diff --git a/src/js/dialogs/sandbox.js b/src/js/dialogs/sandbox.js index d854a3e6..09697a1b 100644 --- a/src/js/dialogs/sandbox.js +++ b/src/js/dialogs/sandbox.js @@ -62,7 +62,7 @@ exports.dialog = { '## Willkommen bei LearnGitBranching!', '', 'Diese Anwendung wurde geschrieben um die umfangreichen', - 'Zusammenhänge beim Arbeiten mit Branches in git zu', + 'Zusammenhänge beim Arbeiten mit Branches in Git zu', 'verdeutlichen. Wir hoffen du hast Spaß und lernst', 'vielleicht sogar etwas dabei!', '', @@ -72,7 +72,7 @@ exports.dialog = { '', '[http://pcottle.github.io/learnGitBranching/?demo](http://pcottle.github.io/learnGitBranching/?demo)', '', - 'Genervt von diesem Fenster? Häng `?NODEM` an die url um es los zu werden, siehe unten:', + 'Genervt von diesem Fenster? Häng `?NODEMO` an die URL um es los zu werden, siehe unten:', '', '[http://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' ] @@ -83,7 +83,7 @@ exports.dialog = { markdowns: [ '## Git-Kommandos', '', - 'Dir steht eine große Zahl von git-Kommandos im Sandkasten-Modus zur Verfügung. Unter anderem', + 'Dir steht eine große Zahl von Git-Befehlen im Sandkasten-Modus zur Verfügung. Unter anderem', '', ' * commit', ' * branch', @@ -101,9 +101,9 @@ exports.dialog = { markdowns: [ '## Teilen macht Spaß!', '', - 'Teile diese git-Bäume mit deinen Freunden mittels `export tree` und `import tree`', + 'Teile diese Git-Bäume mit deinen Freunden mittels `export tree` und `import tree`', '', - 'Hast du Wissenswertes zu git zu vermitteln? Versuch einen Level mit `build level` zu bauen oder probier den Level eines Freundes mit `import level` aus', + 'Hast du Wissenswertes zu Git zu vermitteln? Versuch einen Level mit `build level` zu bauen oder probier den Level eines Freundes mit `import level` aus', '', 'Um alle Kommandos zu sehen, gib `show commands` ein. Darunter gibt\'s kleine Schätze wie `undo` und `reset`', '', diff --git a/src/levels/advanced/multipleParents.js b/src/levels/advanced/multipleParents.js index dd572116..7db24068 100644 --- a/src/levels/advanced/multipleParents.js +++ b/src/levels/advanced/multipleParents.js @@ -4,10 +4,12 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C7\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C4\",\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Multiple parents", + "de_DE": "Mehrere Vorgänger", "zh_CN": "多个父提交记录" }, "hint": { "en_US": "Use `git branch bugWork` with a target commit to create the missing reference.", + "de_DE": "Nutze `git branch bugWork` mit einem Ziel-Commit um die fehlende Referenz zu erstellen.", "zh_CN": "使用`git branch bugWork`加上一个目标提交记录来创建消失的引用。" }, "startDialog": { @@ -98,6 +100,93 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Vorgänger ansteuern", + "", + "Wie der Operator `~` akzeptiert auch der Operator `^` eine optionale Anzahl.", + "", + "Anstatt der Anzahl von Schritten, die zurückgegangen werden soll (das ist das, was man bei `~` angibt), bezeichnet die Anzahl nach `^` welchem Vorgänger bei einem Merge-Commit gefolgt werden soll. Du erinnerst dich, dass ein Merge-Commit mehrere Vorgänger hat; es gilt also aus diesen auszuwählen.", + "", + "Normalerweise folgt Git dem \"ersten\" Vorgänger des Merge-Commit, aber durch Angabe einer Zahl nach dem `^` lässt sich dieses Verhalten ändern.", + "", + "Aber genug gequatscht, schauen wir's uns in Aktion an.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hier sehen wir einen Merge-Commit. Wenn wir einen Checkout von `master^` ohne Zahl machen, wird Git auf den ersten Vorgänger des Commits zurückgehen. ", + "", + "*(In unserer Darstellung befindet sich der erste Vorgänger direkt über dem Merge-Commit.)*" + ], + "afterMarkdowns": [ + "Simpel -- so kennen wir das." + ], + "command": "git checkout master^", + "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Jetzt versuchen wir mal stattdessen den zweiten Vorgänger anzugeben ..." + ], + "afterMarkdowns": [ + "Gesehen? Wir gehen zu dem anderen Vorgänger zurück." + ], + "command": "git checkout master^2", + "beforeCommand": "git checkout HEAD^; git commit; git checkout master; git merge C2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Die Operatoren `^` und `~` geben uns eine Menge Möglichkeiten für das Navigieren durch den Commit-Baum:" + ], + "afterMarkdowns": [ + "Bämm!" + ], + "command": "git checkout HEAD~; git checkout HEAD^2; git checkout HEAD~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Noch abgefahrener: die beiden Operatoren können verkettet werden. Aufgepasst:" + ], + "afterMarkdowns": [ + "Gleicher Ablauf wie zuvor, nur alles in einem Befehl." + ], + "command": "git checkout HEAD~^2~2", + "beforeCommand": "git commit; git checkout C0; git commit; git commit; git commit; git checkout master; git merge C5; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Setzen wir's um", + "", + "Erstelle einen neuen Branch an dem angegebenen Ziel, um diesen Level abzuschließen.", + "", + "Es ist natürlich möglich den Commit einfach direkt anzugeben (also mit sowas wie `C6`), aber ich fordere dich heraus stattdessen die relativen Operatoren zu benutzen!" + ] + } + } + ] + }, "zh_CN": { "childViews": [ { diff --git a/src/levels/index.js b/src/levels/index.js index 8d7df70a..507aa027 100644 --- a/src/levels/index.js +++ b/src/levels/index.js @@ -55,6 +55,7 @@ var sequenceInfo = exports.sequenceInfo = { intro: { displayName: { 'en_US': 'Introduction Sequence', + 'de_DE': 'Einführung', 'ja': 'まずはここから', 'fr_FR': 'Séquence d\'introduction', 'zh_CN': '基础篇', @@ -62,6 +63,7 @@ var sequenceInfo = exports.sequenceInfo = { }, about: { 'en_US': 'A nicely paced introduction to the majority of git commands', + 'de_DE': 'Eine gut abgestimmte Einführung in die wichtigsten Git-Befehle', 'ja': 'gitの基本的なコマンド群をほどよいペースで学ぶ', 'fr_FR': 'Une introduction en douceur à la majorité des commandes git', 'zh_CN': '循序渐进介绍git主要命令', @@ -71,12 +73,14 @@ var sequenceInfo = exports.sequenceInfo = { rampup: { displayName: { 'en_US': 'Ramping Up', + 'de_DE': 'Aufstieg', 'ja': '次のレベルに進もう', 'fr_FR': 'Montée en puissance', 'zh_CN': '进阶篇' }, about: { 'en_US': 'The next serving of 100% git awesomes-ness. Hope you\'re hungry', + 'de_DE': 'Eine Portion Git-Wahnsinn zum Thema Navigation', 'ja': '更にgitの素晴らしさを堪能しよう', 'fr_FR' : 'Le prochain service git 100% excellence. J\'espère que vous êtes affamés', 'zh_CN': '接下来是git的超赞特性。迫不及待了吧!' @@ -85,24 +89,29 @@ var sequenceInfo = exports.sequenceInfo = { remote: { tab: 'remote', displayName: { - 'en_US': 'Push & Pull -- Git Remotes!' + 'en_US': 'Push & Pull -- Git Remotes!', + 'de_DE': 'Push & Pull -- entfernte Repositories' }, about: { - 'en_US': 'Time to share your 1\'s and 0\'s kids; coding just got social' + 'en_US': 'Time to share your 1\'s and 0\'s kids; coding just got social', + 'de_DE': 'Zeit Eure 1en und 0en zu teilen; Coding mit sozialer Komponente' } }, remoteAdvanced: { tab: 'remote', displayName: { - 'en_US': 'To Origin And Beyond -- Advanced Git Remotes!' + 'en_US': 'To Origin And Beyond -- Advanced Git Remotes!', + 'de_DE': 'Bis zum origin und noch weiter' }, about: { - 'en_US': 'And you thought being a benevolent dictator would be fun...' + 'en_US': 'And you thought being a benevolent dictator would be fun...', + 'de_DE': 'Git Remotes für Fortgeschrittene' } }, move: { displayName: { 'en_US': 'Moving Work Around', + 'de_DE': 'Code Umherschieben', // INTL out of sync :( 'ja': 'Rebaseをモノにする', 'fr_FR': 'Maîtrise Rebase, Luke!', @@ -111,6 +120,7 @@ var sequenceInfo = exports.sequenceInfo = { }, about: { 'en_US': 'Get comfortable with modifying the source tree', + 'de_DE': 'Gewöhn dich daran, den Git-Baum zu verändern', // INTL out of sync :( 'ja': '話題のrebaseってどんなものだろう?って人にオススメ', 'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !', @@ -121,6 +131,7 @@ var sequenceInfo = exports.sequenceInfo = { mixed: { displayName: { 'en_US': 'A Mixed Bag', + 'de_DE': 'Ein Kessel Buntes', 'ja': '様々なtips', 'fr_FR': 'Un assortiment', 'ko': '종합선물세트', @@ -128,6 +139,7 @@ var sequenceInfo = exports.sequenceInfo = { }, about: { 'en_US': 'A mixed bag of Git techniques, tricks, and tips', + 'de_DE': 'Eine bunte Mischung von Techniken, Tipps und Tricks', 'ja': 'gitを使う上での様々なtipsやテクニックなど', 'fr_FR': 'Un assortiment de techniques et astuces pour utiliser Git', 'ko': 'Git을 다루는 다양한 팁과 테크닉을 다양하게 알아봅니다', @@ -137,11 +149,13 @@ var sequenceInfo = exports.sequenceInfo = { advanced: { displayName: { 'en_US': 'Advanced Topics', + 'de_DE': 'Themen für Fortgeschrittene', 'fr_FR': 'Sujets Avancés', 'zh_CN': '高级主题' }, about: { 'en_US': 'For the truly brave!', + 'de_DE': '... die nie ein Mensch zuvor gesehen hat.', 'fr_FR': 'Pour les plus courageux !', 'zh_CN': '只为真正的勇士!' } diff --git a/src/levels/intro/branching.js b/src/levels/intro/branching.js index 10d48eca..ba8693d7 100644 --- a/src/levels/intro/branching.js +++ b/src/levels/intro/branching.js @@ -3,6 +3,7 @@ exports.level = { "solutionCommand": "git branch bugFix;git checkout bugFix", "name": { "en_US": "Branching in Git", + "de_DE": "Branches in Git", "ja": "Gitのブランチ", "ko": "Git에서 브랜치 쓰기", "fr_FR": "Gérer les branches avec Git", @@ -10,6 +11,7 @@ exports.level = { }, "hint": { "en_US": "Make a new branch with \"git branch [name]\" and check it out with \"git checkout [name]\"", + "de_DE": 'Lege mit "git branch [Name]" einen neuen Branch an und checke ihn mit "git checkout [Name] aus', "ja": "ブランチの作成(\"git branch [ブランチ名]\")と、チェックアウト(\"git checkout [ブランチ名]\")", "fr_FR": "Faites une nouvelle branche avec \"git branch [nom]\" positionnez-vous dans celle-ci avec \"git checkout [nom]\"", "zh_CN": "用 'git branch [分支名]' 来创建分支,用 'git checkout [分支名]' 切换到分支", @@ -97,6 +99,79 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Branches in Git", + "", + "Branches sind in Git extrem schlank. Sie sind einfach Verweise auf einen bestimmten Commit -- das ist alles. Es ist unter Git-Enthusiasten deshalb gängige Praxis, früh und oft Branches anzulegen.", + "", + "Da das Anlegen von Branches keinen Plattenplatz und Speicher verbraucht, liegt es nahe die Arbeit in kleine logische Häppchen aufzuteilen, anstatt mit wenigen großen, monolithischen Branches zu hantieren.", + "", + "Wir werden sehen wie Commits und Branches zusammengehören sobald wir anfangen mit beiden zu arbeiten. Bis hierhin merk dir einfach, dass ein Branch im Prinzip bedeutet \"ich möchte die Arbeit, die in diesem Commit und seinen Vorgändern steckt, sichern\"." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir mal, wie Branches in der Praxis aussehen.", + "", + "Wir legen einen neuen Branch an und nennen ihn `issue`:" + ], + "afterMarkdowns": [ + "Und das war's auch schon, mehr ist es nicht. Der Branch `issue` zeigt nun auf den Commit `C1`." + ], + "command": "git branch issue", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Lass uns mal ein wenig auf dem neuen Branch arbeiten. Machen wir einen Commit:" + ], + "afterMarkdowns": [ + "Oi! Der Branch `master` hat sich verändert, aber der Branch `issue` nicht. Das liegt daran, dass wir nicht \"auf\" dem neuen Branch waren, weshalb das Sternchen `*` auch hinter `master` steht." + ], + "command": "git commit", + "beforeCommand": "git branch issue" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Sagen wir Git also erst mal auf welchem Branch wir arbeiten wollen, und zwar mit", + "", + "```", + "git checkout [Name]", + "```", + "", + "Das wird uns auf den neuen Branch bringen bevor wir unsere Änderungen committen." + ], + "afterMarkdowns": [ + "Und fertig! Unsere Änderungen wurden im neuen Branch gespeichert." + ], + "command": "git checkout issue; git commit", + "beforeCommand": "git branch issue" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Cool! Jetzt bist du soweit, selbst Branches anzulegen. Wenn dieses Fenster geschlossen wurde, leg einen neuen Branch namens `bugFix` an und schalte auf diesen um." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/intro/commits.js b/src/levels/intro/commits.js index f4a81f36..c5bd80b6 100644 --- a/src/levels/intro/commits.js +++ b/src/levels/intro/commits.js @@ -1,6 +1,7 @@ exports.level = { "name": { "en_US": "Introduction to Git Commits", + "de_DE": "Einführung in Git Commits", "fr_FR": "Introduction aux commits avec Git", "ja": "Gitのコミット", 'ko': 'Git 커밋 소개', @@ -11,6 +12,7 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "hint": { "en_US": "Just type in 'git commit' twice to finish!", + "de_DE": "Gib einfach zweimal 'git commit' ein um den Level abzuschließen", "fr_FR": "Il suffit de saisir 'git commit' deux fois pour réussir !", "zh_CN": "敲两次 'git commit' 就好啦!", "ja": "'git commit'コマンドを2回打てば完成!", @@ -62,6 +64,48 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Commits", + "Ein Commit in ein Git-Repository speichert einen Abbildung aller Dateien in deinem Projektverzeichnis. Es ist wie ein riesiges Kopieren und Einfügen, nur besser.", + "", + "Allerdings will Git die Commits so schlank wie möglich halten, also kopiert es nicht einfach stur das ganze Verzeichnis jedes Mal wenn du committest. Es kann (wenn möglich) Commits als Menge von Änderungen zusammenpacken, von einer Version des Repositorys zur nächsten.", + "", + "Außerdem führt Git ein Protokoll darüber welche Commits wann gemacht wurden, und welcher auf welchen folgt. Deshalb werden die Commits hier mit ihrem Vorgänger über sich gezeigt -- wir verwenden Pfeile zur Darstellung der Beziehung. Dieses Protokoll zu haben ist eine tolle Sache für jeden, der an einem Projekt arbeitet.", + "", + "Das war jetzt eine Menge Neues, aber vorerst kannst du dir Commits einfach als Abbildungen des Projekts vorstellen. Commits sind sehr ressourcenschonend, und zwischen ihnen wechseln geht superschnell!" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Mal sehen wie das in der Praxis ist. Rechts sehen wir ein (kleines) Git-Repository. Es gibt akutell zwei Commits -- den initialen, `C0`, und den danach, `C1`, der irgendwelche Änderungen enthält.", + "", + "Klick die Schaltfläche unten um einen neuen Commit zu erzeugen:" + ], + "afterMarkdowns": [ + "Fertig. Klasse! Wir haben gerade Änderungen gemacht und als Commit im Repository gespeichert. Der Commit, den wir gerade gemacht haben, hat den Vorgänger `C1`; der verweist wiederum auf den Commit, auf dem er basiert: `C0`." + ], + "command": "git commit", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Probier das committen gleich mal aus! Mach zwei Commits um den Level abzuschließen." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/intro/merging.js b/src/levels/intro/merging.js index ff0a0c5f..526fd912 100644 --- a/src/levels/intro/merging.js +++ b/src/levels/intro/merging.js @@ -3,6 +3,7 @@ exports.level = { "solutionCommand": "git checkout -b bugFix;git commit;git checkout master;git commit;git merge bugFix", "name": { "en_US": "Merging in Git", + "de_DE": "Mergen in git", "fr_FR": "Faire des 'merge' (fusions de branches) avec Git", "ko": "Git에서 브랜치 합치기(Merge)", "ja": "ブランチとマージ", @@ -10,6 +11,7 @@ exports.level = { }, "hint": { "en_US": "Remember to commit in the order specified (bugFix before master)", + "de_DE": "Denk dran in der angegebenen Reihenfolge zu committen (erst bugFix, dann master)", "ja": "指示された順番でコミットすること(masterの前にbugFixで)", "fr_FR": "Pensez à faire des commits dans l'ordre indiqué (bugFix avant master)", "zh_CN": "记住按指定的顺序提交(bugFix先于master)", @@ -88,6 +90,75 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Branches und Mergen", + "", + "Super! Wir wissen jetzt, wie man committet und einen Branch anlegt. Jetzt müssen wir nur noch rauskriegen, wie man die Arbeit, die in verschiedenen Branches steckt, zusammenführen kann. Dann können wir einen neuen Branch erstellen, darin ein neues Feature entwickeln, und das dann in den ursprünglichen Zweig integrieren.", + "", + "Die einfachste Methode, mit der man Branches zusammenführen kann, ist `git merge`. Das Mergen erzeugt in git einen speziellen Commit, der zwei Vorgänger hat. Ein solcher Commit bedeutet im Prinzip \"ich möchte alle Arbeit von dem Vorgänger hier und dem dort *und* allen ihren jeweiligen Vorgängern miteinander kombinieren\".", + "", + "Grafisch dargestellt ist es einfacher zu verstehen, lass es uns mal ansehen" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hier haben wir zwei Branches; jeder besteht jeweils aus einem eigenen Commit. Das bedeutet, dass keiner der beiden Branches alle Inhalte des gesamten Repositorys kennt. Das werden wir mit einem Merge ändern.", + "", + "Wir werden den Branch `bugFix` in `master` integrieren" + ], + "afterMarkdowns": [ + "Wow! Hast du das gesehen? Zunächst mal zeigt `master` jetzt auf einen Commit mit zwei Vorgängern. Wenn du den beiden Pfeilen immer weiter folgst, kommst du an jedem Commit im Repository vorbei. Das heißt `master` enthält jetzt alles, was es im Repository gibt.", + "", + "Siehst du außerdem wie sich die Farben der Commits verändert haben? Um die Vorgänge zu verdeutlichen hab ich etwas Farbe ins Spiel gebracht. Jeder Branch hat seine eindeutige Farbe. Jeder Merge Commit bekommt als Farbe eine Mischung aus den Farben seiner Vorgänger.", + "", + "Wir sehen also, dass die Farbe des Branch `master` in alle Commits gemischt wurde, die von `bugFix` aber nicht. Ändern wir das ..." + ], + "command": "git merge bugFix", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Mergen wir `master` in `bugFix`:" + ], + "afterMarkdowns": [ + "Da `bugFix` ein Vorgänger von `master` war, musste git hier kaum etwas tun; es verschiebt `bugFix` einfach auf den Commit, auf den auch `master` zeigt.", + "", + "Jetzt haben alle Commits dieselbe Farbe, das heißt jeder Branch enthält die Informationen des gesamten Repositorys! Juhu!" + ], + "command": "git checkout bugFix; git merge master", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit; git merge bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Führe folgendes aus, um diesen Level zu schaffen:", + "", + "* Lege einen neuen Branch `bugFix` an", + "* Checke `bugFix` aus mittels `git checkout bugFix`", + "* Mach einen Commit", + "* Geh mit `git checkout` zum `master` zurück", + "* Mach noch einen Commit", + "* Merge den Branch `bugFix` in `master` mit `git merge`", + "", + "*Denk dran, du kannst diese Meldung mit dem Befehl `help level` so oft anzeigen, wie du willst!*" + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/intro/rebasing.js b/src/levels/intro/rebasing.js index 9c1c7026..6264b642 100644 --- a/src/levels/intro/rebasing.js +++ b/src/levels/intro/rebasing.js @@ -3,6 +3,7 @@ exports.level = { "solutionCommand": "git checkout -b bugFix;git commit;git checkout master;git commit;git checkout bugFix;git rebase master", "name": { "en_US": "Rebase Introduction", + "de_DE": "Einführung in Rebase", "ja": "Rebaseの解説", "fr_FR": "Introduction à rebase", "ko": "리베이스(rebase)의 기본", @@ -10,6 +11,7 @@ exports.level = { }, "hint": { "en_US": "Make sure you commit from bugFix first", + "de_DE": "Geh vor dem committen sicher, dass du auf bugFix arbeitest", "ja": "初めにbugFixを指した状態でコミットする", "fr_FR": "Assurez-vous de bien faire votre en premier votre commit sur bugFix", "ko": "bugFix 브랜치에서 먼저 커밋하세요", @@ -86,6 +88,73 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Rebase", + "", + "Der zweite Weg um Inhalte aus verschiedenen Branches zu kombinieren ist `git rebase`. Rebasen nimmt im Prinzip eine Menge von Commits, \"kopiert\" sie und packt sie auf etwas anderes drauf.", + "", + "Auch wenn das erst mal komisch klingt liegt der Vorteil von Rebase darin, dass man es benutzen kann um hübsch lineare Abfolgen von Commits zu erhalten. Das Commit-Protokoll des Repositorys wird durch Rebase eine ganze Ecke einfacher aussehen, weil Merge Commits vermieden werden.", + "", + "Schauen wir's uns mal in Aktion an ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hier haben wir wieder zwei Branches; wie du siehst ist `bugFix` aktuell ausgewählt (sieht man am `*`).", + "", + "Wir würden jetzt gerne unsere Arbeit aus `bugFix` direkt auf den `master` packen. Das Ergebnis wäre, dass alle aktuellen Änderungen in `master` auch im Branch `bugFix` sind.", + "", + "Das machen wir mit dem Befehl `git rebase`:" + ], + "afterMarkdowns": [ + "Hammer! Was wir in `bugFix` gemacht haben ist jetzt oben auf `master` draufgepackt und wir haben eine schön lineare Abfolge von Commits bekommen.", + "", + "Commit `C3` existiert immer noch irgendwo (deswegen ist er blaß dargestellt) und `C3'` ist die \"Kopie\" die wir auf den `master` gepackt haben.", + "", + "Aber `master` ist jetzt nicht aktualisiert worden, lass uns das gerade noch nachholen ..." + ], + "command": "git rebase master", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Jetzt sind wir im `master`. Lass uns den mal auf `bugFix` rebasen ..." + ], + "afterMarkdowns": [ + "So! Da `master` ein Vorgänger von `bugFix` war konnte Git hier einfach den Bezeichner `master` auf denselben Commit schieben, auf den auch `bugFix` zeigt." + ], + "command": "git rebase bugFix", + "beforeCommand": "git commit; git checkout -b bugFix C1; git commit; git rebase master; git checkout master" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um dieses Level abzuschließen musst du folgendes tun:", + "", + "* Einen neuen Branch namens `bugFix` auschecken", + "* Einen Commit machen", + "* Zurück zum `master` wechseln und noch einmal committen", + "* `bugFix` auschecken und auf den `master` rebasen", + "", + "Viel Erfolg!" + ] + } + } + ] + }, "ja": { "childViews": [ { From 0152976952a76ba6ccd8e5d3f46fbe76a3208255 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Wed, 18 Dec 2013 21:47:10 +0100 Subject: [PATCH 06/47] Translated two more levels --- src/js/intl/strings.js | 4 +- src/levels/mixed/describe.js | 69 ++++++++++++++++++++++++++- src/levels/mixed/grabbingOneCommit.js | 40 ++++++++++++++++ 3 files changed, 109 insertions(+), 4 deletions(-) diff --git a/src/js/intl/strings.js b/src/js/intl/strings.js index 6f418777..f0fd7549 100644 --- a/src/js/intl/strings.js +++ b/src/js/intl/strings.js @@ -268,7 +268,7 @@ exports.strings = { 'git-error-args-many': { '__desc__': 'One of the error messages for git', 'en_US': 'I expect at most {upper} argument(s) for {what}', - 'de_DE': 'Ich benötige maximal {upper} Argumente für {what}', + 'de_DE': 'Ich benötige maximal {upper} Argument(e) für {what}', 'zh_CN': '{what} 期望最多 {upper} 个参数', 'fr_FR': 'J\'attends au plus {upper} argument(s) pour {what}' }, @@ -276,7 +276,7 @@ exports.strings = { 'git-error-args-few': { '__desc__': 'One of the error messages for git', 'en_US': 'I expect at least {lower} argument(s) for {what}', - 'de_DE': 'Ich benötige höchstens {lower} Argumente für {what}', + 'de_DE': 'Ich benötige mindestens {lower} Argument(e) für {what}', 'zh_CN': '{what} 期望最少 {lower} 个参数', 'fr_FR': 'J\'attends au moins {upper} argument(s) pour {what}' }, diff --git a/src/levels/mixed/describe.js b/src/levels/mixed/describe.js index c590b4b5..8853df5b 100644 --- a/src/levels/mixed/describe.js +++ b/src/levels/mixed/describe.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git commit ", "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C4\",\"id\":\"side\",\"remoteTrackingBranchID\":null},\"bugFix\":{\"target\":\"C6\",\"id\":\"bugFix\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C3\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"tags\":{\"v0\":{\"target\":\"C0\",\"id\":\"v0\",\"type\":\"tag\"},\"v1\":{\"target\":\"C3\",\"id\":\"v1\",\"type\":\"tag\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}", "name": { - "en_US": "Git Describe" + "en_US": "Git Describe", + "de_DE": "Git Describe" }, "hint": { - "en_US": "Just commit once on bugFix when you're ready to move on" + "en_US": "Just commit once on bugFix when you're ready to move on", + "de_DE": "Committe nur einmal auf bugFix, wenn du soweit bist" }, "startDialog": { "en_US": { @@ -71,6 +73,69 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Git Describe", + "", + "Weil Tags so super als \"Anker\" im Repository dienen können bietet Git einen Befehl um zu *beschreiben* wo du dich relativ zum nächsten \"Anker\" (also Tag) befindest. Und der heißt `git describe`.", + "", + "Er hilft dir dabei, dir einen Überblick zu verschaffen nachdem du viele Commits im Log zurück- oder vorgegangen bist; das kann vorkommen nachdem du ein `git bisect` (eine Fehlersuche) abgeschlossen hast oder wenn du dich an den Rechner eines Kollegen setzt, der gerade aus dem Urlaub gekommen ist." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Der Befehl ist folgendermaßen aufgebaut:", + "", + "`git describe `", + "", + "Dabei ist `` jeder beliebige Name, der einem Commit zugeordnet ist (Branch, Tag etc). Wenn du keinen angibst benutzt Git `HEAD`, also den aktuellen Checkout.", + "", + "Die Befehlsausgabe sieht so aus:", + "", + "`__g`", + "", + "`` ist dabei der nächstliegende Tag in den Vorgänger-Commits, `` zeigt an, wieviele Commits dieses Tag entfernt ist und `` ist das SHA des Commits, auf den das Tag zeigt." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns das schnell an einem Beispiel an. Für den folgenden Baum:" + ], + "afterMarkdowns": [ + "Der Befehl `git describe master` würde folgendes ausgeben:", + "", + "`v1_2_gC2`", + "", + "Wohingegen `git describe side` dies ausgeben würde:", + "", + "`v2_1_gC4`" + ], + "command": "git tag v2 C3", + "beforeCommand": "git commit; go -b side HEAD~1; gc; gc; git tag v1 C0" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Das ist so ziemlich alles, was es über `git describe` zu wissen gibt. Versuch ein paar Orte in diesem Level damit auszugeben, um ein Gefühl dafür zu bekommen.", + "", + "Sobald du fertig bist, mach einfach einen Commit um den Level abzuschließen. Der geht auf's Haus. :P" + ] + } + } + ] } } }; diff --git a/src/levels/mixed/grabbingOneCommit.js b/src/levels/mixed/grabbingOneCommit.js index 99a43d71..db2d56f7 100644 --- a/src/levels/mixed/grabbingOneCommit.js +++ b/src/levels/mixed/grabbingOneCommit.js @@ -16,11 +16,13 @@ exports.level = { "name": { "ko": "딱 한개의 커밋만 가져오기", "en_US": "Grabbing Just 1 Commit", + "de_DE": "Einen Commit pflücken", "ja": "Grabbing Just 1 Commit", "zh_CN": "只取一个提交" }, "hint": { "en_US": "Remember, interactive rebase or cherry-pick is your friend here", + "de_DE": "Vergiss nicht: hier kommst du mit interaktivem Rebase oder Cherry-Picking weiter", "ja": "このレベルではインタラクティブモードのrebaseやcherry-pickがクリアのカギです", "ko": "대화식 리베이스(rebase -i)나 or 체리픽(cherry-pick)을 사용하세요", "zh_CN": "记住,交互式 rebase 或者 cherry-pick 会很有帮助" @@ -65,6 +67,44 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Lokale Commit-Haufen", + "", + "Folgende Situation habe ich beim Entwickeln des öfteren: ich bin auf der Suche nach einem Bug, aber er ist echt schwer zu finden. Um ihm auf die Spur zu kommen schreibe ich mehrere Debug-Kommandos und print-Befehle in den Code.", + "", + "Die committe ich auch immer wieder, je weiter die Suche mich trägt; natürlich in einem lokalen Branch. Schließlich finde ich den Bug, fixe ihn und freue mich!", + "", + "Einziges Problem ist, dass ich diesen `bugFix` jetzt zurück in den `master` kriegen muss. Wenn ich einfach den `master` vorspule oder meinen Branch hinein merge, bekäme der `master` auch die ganzen Debug-Befehle, was nicht gewünscht ist. Das muss anders gehen ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wir müssten Git sagen können, dass es nur einen Commit herüber kopieren soll. Das ist genauso wie die Level vorhin zum Code-Verschieben. Wir können dieselben Befehle benutzen:", + "", + "* `git rebase -i`", + "* `git cherry-pick`", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Da dies ein späterer Level ist überlasse ich es dir zu entscheiden, welchen Befehl du benutzen willst. Aber um da Level zu schaffen musst du irgendwie sicherstellen, dass `maste` den Commit bekommt, auf den `bugFix` zeigt." + ] + } + } + ] + }, // INTL out of sync :( "ja": { "childViews": [ From c676c2f1aed7aa3dd558760f1194db9bd95b3ba0 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Thu, 19 Dec 2013 21:08:07 +0100 Subject: [PATCH 07/47] More levels translated --- src/levels/mixed/jugglingCommits.js | 43 +++++++++++++++ src/levels/mixed/jugglingCommits2.js | 45 ++++++++++++++++ src/levels/mixed/tags.js | 58 +++++++++++++++++++- src/levels/rampup/cherryPick.js | 63 +++++++++++++++++++++- src/levels/rampup/detachedHead.js | 80 ++++++++++++++++++++++++++++ 5 files changed, 285 insertions(+), 4 deletions(-) diff --git a/src/levels/mixed/jugglingCommits.js b/src/levels/mixed/jugglingCommits.js index 4368e8cd..e9de3eca 100644 --- a/src/levels/mixed/jugglingCommits.js +++ b/src/levels/mixed/jugglingCommits.js @@ -20,11 +20,13 @@ exports.level = { "name": { "ko": "커밋들 갖고 놀기", "en_US": "Juggling Commits", + "de_DE": "Jonglieren mit Commits", "ja": "Juggling Commits", "zh_CN": "提交变换戏法" }, "hint": { "en_US": "The first command is git rebase -i HEAD~2", + "de_DE": "Der erste Befehl ist git rebase -i HEAD~2", "ja": "最初に打つコマンドはgit rebase -i HEAD~2", "ko": "첫번째 명령은 git rebase -i HEAD~2 입니다", "zh_CN": "第一个命令是 'git rebase -i HEAD~2'" @@ -71,6 +73,47 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Jonglieren mit Commits", + "", + "Eine weitere häufig vorkommende Situation: du hast einige Änderungen in `newImage` und weitere Änderungen in `caption`. Die Änderungen hängen voneineander ab, das heißt in diesem Fall `caption` ist ein Nachfolger von `newImage`.", + "", + "Nun kann es vorkommen, dass du einen früheren Commit verändern willst. In unserem Fall will die Design-Abteilung, dass die Abmessungen in `newImage` leicht verändert werden, obwohl das mitten in unserer History liegt!" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um das zu schaffen gehen wir wie folgt vor:", + "", + "* Wir sortieren die Commits mit `git rebase -i` so um, dass der, den wir ändern wollen, ganz oben liegt.", + "* Wir verändern den Commit mit `git commit --amend`.", + "* Dann sortieren wir die Commit mit einem erneuten `git rebase -i` wieder in die alte Reihenfolge.", + "* Schließlich aktualisieren wir den `master` auf das Ende unseres fertigen Baums, um diesen Level abzuschließen.", + "", + "Es gibt sehr viele Wege um das Endziel dieses Levels zu erreichen (ich sehe, du schielst auf `cherry-pick`) und wir werden uns später noch andere ansehen. Aber für's erste lass uns diese Methode ausprobieren." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Beachte den geschilderten Zielzustand. Da wir die Commits zweimal umsortieren bekommen sie jedesmal ein Apostroph hinzugefügt (weil sie jedesmal kopiert werden). Ein weiteres Apostroph entsteht durch den `commit --amend`.", + "", + "Zuguterletzt noch eine Bemerkung: ich kann Level nun auf Struktur und Apostroph-Differenz prüfen. So lange wie dein `master` am Ende dieselbe Strukutr und Apostroph-Differenz aufweist wie der Ziel-`master`, ist der Level bestanden." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/mixed/jugglingCommits2.js b/src/levels/mixed/jugglingCommits2.js index 97945b4d..03f04d1e 100644 --- a/src/levels/mixed/jugglingCommits2.js +++ b/src/levels/mixed/jugglingCommits2.js @@ -19,11 +19,13 @@ exports.level = { "name": { "ko": "커밋 갖고 놀기 #2", "en_US": "Juggling Commits #2", + "de_DE": "Jonglieren mit Commits Teil 2", "ja": "コミットをやりくりする その2", "zh_CN": "提交交换戏法 #2" }, "hint": { "en_US": "Don't forget to forward master to the updated changes!", + "de_DE": "Vergiss nicht den master auf die aktuelle Version vorzuspulen", "ja": "masterのポインタを先に進めることを忘れずに!", "ko": "master를 변경 완료한 커밋으로 이동(forward)시키는 것을 잊지 마세요!", "zh_CN": "别忘记了将 master 快进到最新的更新上!" @@ -72,6 +74,49 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Jonglieren mit Commits Teil 2", + "", + "Du solltest \"Jonglieren mit Commits\" (den vorherigen Level) bestanden haben, bevor du dich an diesem hier versuchst.", + "", + "Wie du im letzten Level gesehen hast haben wir `git rebase -i` genutzt, um die Commits neu anzuordnen. Sobald der Commit, den wir ändern wollte, ganz oben war, konnten wir das auch einfach mit `git commit --amend` tun. Danach haben wir die alte Reihenfolge wiederhergestellt.", + "", + "Das einzige Problem ist hier, dass da eine Menge Umsortieren stattfindet, was zu Rebase-Konflikten führen kann. Schauen wir uns also eine Methode mit `git cherry-pick` an." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Wie du dich erinnerst macht `git cherry-pick` eine Kopie des angegebenen Commits und fügt sie an `HEAD` an (es sei denn der Commit ist ein Vorgänger von `HEAD`).", + "", + "Hier eine kleine Demo zur Erinnerung:" + ], + "afterMarkdowns": [ + "Schick! Und weiter geht's." + ], + "command": "git cherry-pick C2", + "beforeCommand": "git checkout -b bugFix; git commit; git checkout master; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "In diesem Level geht es also auch um das Ziel den Commit `C2` zu modifizieren, aber ohne `git rebase -i` zu benutzen. Ich überlass es dir herauszufinden, wie das gehen soll. :D", + "", + "Nicht vergessen, die genaue Anzahl von Kopien (d.h. Apostrophs) ist nicht ausschlaggebend, nur die Differenz. Der Level ist zum Beispiel auch gelöst, wenn dein fertiger Baum dieselbe Struktur wie der Ziel-Baum hat, aber *überall* ein Apostroph mehr aufweist." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/mixed/tags.js b/src/levels/mixed/tags.js index 8a18a1cf..7d551c80 100644 --- a/src/levels/mixed/tags.js +++ b/src/levels/mixed/tags.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git tag v1 side~1;git tag v0 master~2;git checkout v1", "startTree": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"side\":{\"target\":\"C3\",\"id\":\"side\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\",\"C4\"],\"id\":\"C5\"}},\"tags\":{},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { - "en_US": "Git Tags" + "en_US": "Git Tags", + "de_DE": "Git Tags" }, "hint": { - "en_US": "you can either check out the commit directly or simply checkout the tag!" + "en_US": "you can either check out the commit directly or simply checkout the tag!", + "de_DE": "Du kannst den Checkout entweder direkt auf den Commit oder das Tag machen." }, "startDialog": { "en_US": { @@ -60,6 +62,58 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Tags", + "", + "Wie du aus den vorhergehenden Levels weißt sind Branches einfach durch die Gegend zu schieben und zeigen of auf verschiedene Commits, während die Arbeit in ihnen fortschreitet. Ein Branch wird oft verändert, manchmal nur temporär, und ist ständig in Bewegung.", + "", + "Da das so ist fragst du dich vielleicht, ob es nicht eine Möglichkeit gibt, eine bestimmte Stelle in deiner Projekt-History *permanent* zu kennzeichnen. Kann man nicht zum Beispiel für große Releases und Meilensteine nicht einen Commit mit etwas festerem kennzeichnen, als mit einem Branch-Namen?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Aber klar! In Git gibt es genau zu diesem Zweck Tags -- sie kennzeichnen einen Commit (ziemlich) permanent als Meilenstein oder ähnliches, und man kann sie ansprechen wie Branch-Namen.", + "", + "Noch viel wichtiger, Tags verändern nicht ihre Position wenn man Commits hinzufügt. Du kannst ein Tag nicht in diesem Sinne auschecken und dann Modifikationen darauf committen. Tags sind Anker im Commit-Baum, die bestimmte Stellen anzeigen.", + "", + "Lass uns anschauen wie Tags in der Praxis funktionieren." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Lass uns ein Tag bei `C1` anlegen und damit die Version 1 unseres Prototyps markieren." + ], + "afterMarkdowns": [ + "Peng! Ziemlich einfach. Wir haben das Tag `v1` genannt und lassen es auf `C1` zeigen. Wenn du den Commit weglässt wir das Tag für den Commit erzeugt, auf den `HEAD` zeigt." + ], + "command": "git tag v1 C1", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level zu schaffen, erstelle einfach die Tags wie sie in der Zielbeschreibung stehen und mach dann einen Checkout auf `v1`. Beachte wie du dabei in den \"Detached HEAD\" Zustand gehst -- das liegt daran, dass du keine Commits direkt auf das `v1` Tag machen kannst.", + "", + "Im nächsten Level schauen wir uns dann interessantere Anwendungsfälle für Tags an." + ] + } + } + ] } } }; diff --git a/src/levels/rampup/cherryPick.js b/src/levels/rampup/cherryPick.js index bc3774c0..bad03183 100644 --- a/src/levels/rampup/cherryPick.js +++ b/src/levels/rampup/cherryPick.js @@ -7,10 +7,12 @@ exports.level = { }, "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"side\":{\"target\":\"C5\",\"id\":\"side\"},\"another\":{\"target\":\"C7\",\"id\":\"another\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C1\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { - "en_US": "Cherry-pick Intro" + "en_US": "Cherry-pick Intro", + "de_DE": "Einführung Cherry-picking" }, "hint": { - "en_US": "git cherry-pick followed by commit names!" + "en_US": "git cherry-pick followed by commit names!", + "de_DE": "git cherry-pick gefolgt von Commit-Namen." }, "startDialog": { "en_US": { @@ -69,6 +71,63 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Inhalte verschieben", + "", + "Bis jetzt haben wir uns die Grundlagen von Git angeschaut -- comitten, verzweigen und sich im Commit-Baum bewegen. Nur damit lässt sich schon 90% der Macht von Git-Repositories nutzen und die meisten Anforderungen von Entwicklern erfüllen.", + "", + "Die übrigen 10% jedoch können in komplexeren Abläufen sehr hilfreich sein (oder wenn man sich in eine schwierige Lage manövriert hat). Das nächste was wir uns anschauen, ist, Inhalte durch den Commit-Baum zu schieben. Es gibt dem Entwickler die Möglichkeit in präziser, eloquenter Manier zu sagen \"Ich will diese Inhalte hier und diese dort haben\".", + "", + "Das klingt vielleicht nach einer Menge, aber es ist sehr einfach." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## git cherry-pick", + "", + "Der erste Befehl in dieser Serie ist `git cherry-pick`. Er sieht so aus:", + "", + "* `git cherry-pick <...>`", + "", + "Er ist eine einfache Möglichkeit um auszudrücken, dass du eine Folge von Commits unter deinen aktuellen Checkout (also `HEAD`) hängen möchtest. Ich persönlich liebe `cherry-pick`, weil es wenig Magic enthält und einfach zu verstehen ist.", + "", + "Schauen wir's uns mal an.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hier haben wir ein Repository mit einigem Zeugs im Branch `side`, das wir in den Branch `master` kopieren wollen. Das könnten wir mit einem Rebase machen (wie bereits gesehen), aber schauen wir mal wie das mit `cherry-pick` geht." + ], + "afterMarkdowns": [ + "Das war's! Wir wollten die commits `C2` und `C4` und Git hat die einfach unter unseren aktuellen Checkout kopiert. So einfach ist das." + ], + "command": "git cherry-pick C2 C4", + "beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level zu schaffen musst du einfach nur einige Commits aus den drei gezeigten Branches in den `master` kopieren. Der Zielbaum zeigt dir, welche.", + "" + ] + } + } + ] } } }; diff --git a/src/levels/rampup/detachedHead.js b/src/levels/rampup/detachedHead.js index 5bf58db8..3105ee48 100644 --- a/src/levels/rampup/detachedHead.js +++ b/src/levels/rampup/detachedHead.js @@ -4,10 +4,12 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Detach yo' HEAD", + "de_DE": "Den Kopf abtrennen", "zh_CN": "分离HEAD" }, "hint": { "en_US": "Use the label (hash) on the commit for help!", + "de_DE": "Benutze den Bezeichner (den Hash) des Commits.", "zh_CN": "使用提交记录上的标签(hash)来求助!" }, "startDialog": { @@ -89,6 +91,84 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Navigation durch Git", + "", + "Bevor wir uns einige fortgeschrittene Konzepte in Git ansehen ist es wichtig, verschiedene Wege zum Navigieren durch den Commit-Baum, der das Projekt enthält, zu kennen.", + "", + "Sobald du das drauf hast, vergrößern sich deine Möglichkeiten in allen anderen Git-Befehlen.", + "", + "", + "", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## HEAD", + "", + "Erst mal müssen wir über `HEAD` reden. `HEAD` ist ein Alias für den Commit, der gerade ausgecheckt ist -- es ist im Prinzip der Commit, an den du deinen nächsten Commit hängst.", + "", + "`HEAD` zeigt immer auf den neuesten Commit. Die meisten Git-Befehle, die den Baum verändern, fangen damit an dass sie `HEAD` verschieben.", + "", + "Normalerweise zeigt `HEAD` auf einen Branch-Namen (z.B. `bugFix`). Wenn du einen Commit machst, wird `bugFix` auf diesen Commit geschoben, und `HEAD` (da es auf `bugFix` zeigt) automatisch auch." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns das mal in Aktion an. Wir werden hier `HEAD` vor und nach dem Commit anzeigen." + ], + "afterMarkdowns": [ + "Siehst du? `HEAD` war die ganze Zeit unter `master` versteckt." + ], + "command": "git checkout C1; git checkout master; git commit; git checkout C2", + "beforeCommand": "" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "### HEAD abkoppeln", + "", + "`HEAD` abzukoppeln bedeutet, es direkt an einen bestimmten Commit zu hängen, anstatt an einen Branch. Wir gelangen dadurch in den \"detached HEAD state\". So sieht's vorher aus:", + "", + "`HEAD` -> `master` -> `C1`", + "" + ], + "afterMarkdowns": [ + "Und jetzt:", + "", + "`HEAD` -> `C1`" + ], + "command": "git checkout C1", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level abzuschließen, lass uns mal `HEAD` von `bugFix` abkoppeln und an den Commit hängen.", + "", + "Gib den Commit mit seinem Hash an. Der Hash jedes Commits steht in dem Kreis, der den Commit darstellt." + ] + } + } + ] + }, "zh_CN": { "childViews": [ { From fd84fb5cd9ce6b6b3fa96c0839a139a80a26246d Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Thu, 19 Dec 2013 21:23:08 +0100 Subject: [PATCH 08/47] Translated interactive rebase level --- src/levels/rampup/interactiveRebase.js | 71 +++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/levels/rampup/interactiveRebase.js b/src/levels/rampup/interactiveRebase.js index 6c1ae72e..37a614db 100644 --- a/src/levels/rampup/interactiveRebase.js +++ b/src/levels/rampup/interactiveRebase.js @@ -7,10 +7,12 @@ exports.level = { }, "startTree": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\"},\"overHere\":{\"target\":\"C1\",\"id\":\"overHere\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "hint": { - "en_US": "you can use either branches or relative refs (HEAD~) to specify the rebase target" + "en_US": "you can use either branches or relative refs (HEAD~) to specify the rebase target", + "de_DE": "Du kannst entweder Branches oder relative Ref-Angaben (z.B. HEAD~) benutzen, um das Ziel des Rebase anzugeben." }, "name": { - "en_US": "Interactive Rebase Intro" + "en_US": "Interactive Rebase Intro", + "de_DE": "Einführung Interactive Rebase" }, "startDialog": { "en_US": { @@ -77,6 +79,71 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Interaktiver Rebase", + "", + "Cherry-pick ist großartig wenn du genau weißt, welche Commits du willst (_und_ ihre jeweiligen Hashes kennst) -- es ist dann schwer an Einfachheit zu überbieten.", + "", + "Aber wie sieht es aus, wenn du die Commits nicht genau kennst, die du brauchst? Zum Glück bietet Git auch dafür eine Lösung an. Das können wir mit interaktivem Rebase machen -- die beste Art sich eine Serie von Commits in einem Rebase genau anzusehen.", + "", + "Schauen wir uns die Details an ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Interaktives Rebase bedeutet einfach nur, dass man dem `rebase` Befehl die Option `-i` hinzufügt.", + "", + "Wenn du das machst, zeigt Git dir jeden einzelnen Commit, der durch den Rebase kopiert werden würde. Es zeigt dir die Hashes und Kommentare, was gut ist um einen Überblick zu bekommen.", + "", + "In echtem Git besteht dieser Dialog daraus, die Commits in einem Text-Editor angezeigt zu bekommen. Für unsere Zwecke hab ich ein kleines Dialog-Fenster gebaut, dass sich ähnlich verhält." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wenn sich der Dialog für den interaktiven Rebase öffnet, kannst du drei Dinge tun:", + "", + "* Du kannst die Reihenfolge der Commits durch Ziehen und Ablegen ändern.", + "* Du kannst Git sagen, einen Commit beim Rebase zu ignorieren -- im Dialog durch die Schaltfläche `pick` dargestellt.", + "* Außerdem kannst du Commit zusammenfassen (squash). Leider wird das hier nicht unterstützt, aber in echtem Git fasst es Commits zu einem zusammen.", + "", + "Super! Schauen wir uns ein Beispiel an." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Wenn du die Schaltfläche anklickst wird sich der Rebase-Dialog öffnen. Veränder die Reihenfolge der Commits oder klick bei einigen auf `pick` und schau dir das Ergebnis an." + ], + "afterMarkdowns": [ + "Bämm! Git hat die Commits genau so kopiert, wie du es ausgewählt hast." + ], + "command": "git rebase -i HEAD~4 --aboveAll", + "beforeCommand": "git commit; git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um dieses Level zu schaffen mach einen interaktiven Rebase, um genau doie Reihenfolge zu erzeugen die im Ziel-Baum angezeigt wird. Denk daran, dass du jederzeit mit `undo` oder `reset` Fehler rückgängig machen kannst. :D" + ] + } + } + ] } } }; From abb249b3ed16e8ae65bff566f9f398531acd32b4 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Fri, 20 Dec 2013 18:00:50 +0100 Subject: [PATCH 09/47] More translated levels --- src/levels/rampup/relativeRefs.js | 77 +++++++++++++++++++++++++++ src/levels/rampup/relativeRefs2.js | 70 ++++++++++++++++++++++++ src/levels/rampup/reversingChanges.js | 65 ++++++++++++++++++++++ src/levels/rebase/manyRebases.js | 21 ++++++++ src/levels/remote/clone.js | 63 +++++++++++++++++++++- 5 files changed, 294 insertions(+), 2 deletions(-) diff --git a/src/levels/rampup/relativeRefs.js b/src/levels/rampup/relativeRefs.js index 8891e6d6..0aac617c 100644 --- a/src/levels/rampup/relativeRefs.js +++ b/src/levels/rampup/relativeRefs.js @@ -4,10 +4,12 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Relative Refs (^)", + "de_DE": "Relative Referenzen (^)", "zh_CN": "相对引用(^)" }, "hint": { "en_US": "Remember the Caret (^) operator!", + "de_DE": "Denk an den Dach-Operator (^)!", "zh_CN": "记住插入(^)操作符!" }, "startDialog": { @@ -86,6 +88,81 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Rleative Referenzen", + "", + "Es kann etwas mühselig werden, sich in einem Commit-Baum mittels Angabe der Hashes zu bewegen. Im echten Leven hat man normalerweise keine hübsche Visualisierung des Baumes neben seinem Terminal, also benutzt man `git log` um die Hashes zu sehen.", + "", + "Außerdem sind die echten Hashes sehr viel länger und nicht fortlaufend nummeriert. Beispielsweise heißt der Hash, mit dem ich den letzten Level committet habe, in echt `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. Nicht gerade einprägsam ...", + "", + "Zum Glück ist Git intelligent wenn es um die Hashes geht. Du musst nur soviele Zeichen eines Hashes angeben, bis der Hash eindeutig ist. Ich kann also `fed2` eingeben anstatt die komplette Zeichenkette tippen zu müssen." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wie ich schon sagte: Commits über ihren Hash zu referenzieren ist nicht gerade der bequemste Weg. Weshalb es in Git relative Referenzen gibt. Welche super sind!", + "", + "Mit relativen Referenzen kann man bei einem leicht zu merkenden Bezeichner anfangen (zum Beispiel dem Branch-Namen `bugFix` oder der Referenz `HEAD`) und sich von dort vorarbeiten.", + "", + "Relative Referenzierung von Commits kann komplex sein, aber wir starten mit zwei einfachen Beispielen:", + "", + "* Geh einen Commit zurück mit `^`", + "* Geh eine bestimmte Anzahl von Commits zurück mit `~`" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns zuerst den Dach-Operator (`^`) an. Jedes mal wenn du ihn hinter einen Referenz-Namen setzt, sagst du Git damit, dass es zum Vorgänger des angegebenen Commits gehen soll.", + "", + "Das heißt `master^` ist gleichbedeutend mit \"direkter Vorgänder des Commits, auf den `master` zeigt\".", + "", + "`master^^` ist also der Vorgänger des Vorgängers von `master`.", + "", + "Wir checken jetzt mal den Commit vor `master` aus:" + ], + "afterMarkdowns": [ + "Bämm! Fertig. Einfacher, als den Commit-Hash zu tippen (oder zu kopieren)." + ], + "command": "git checkout master^", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Du kannst auch `HEAD` als Basis für relative Referenzen benutzen. Lass uns das ein paar verwenden, um uns im Commit-Baum nach oben zu bewegen." + ], + "afterMarkdowns": [ + "Das war einfach. Wir reisen mit `HEAD^` in der Zeit zurück." + ], + "command": "git checkout C3; git checkout HEAD^; git checkout HEAD^; git checkout HEAD^", + "beforeCommand": "git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um dieses Level abzuschließen musst du den direkten Vorgänger von `bugFix` auschecken. Dadurch wirst du `HEAD` von `bugFix` abkoppeln.", + "", + "Du kannst natürlich den Hash angeben, aber versuch doch relative Referenzen zu benutzen!" + ] + } + } + ] + }, "zh_CN": { "childViews": [ { diff --git a/src/levels/rampup/relativeRefs2.js b/src/levels/rampup/relativeRefs2.js index dc9abcea..f8a69da4 100644 --- a/src/levels/rampup/relativeRefs2.js +++ b/src/levels/rampup/relativeRefs2.js @@ -4,10 +4,12 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C5\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C3\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"C2\",\"id\":\"HEAD\"}}", "hint": { "en_US": "You'll need to use at least one direct reference (hash) to complete this level", + "de_DE": "Du musst mindestens einen Hash benutzen, um dieses Level zu schaffen", "zh_CN": "这一关至少要用到一次直接引用(hash)" }, "name": { "en_US": "Relative Refs #2 (~)", + "de_DE": "Relative Referenzen #2 (~)", "zh_CN": "相对引用2(~)" }, "startDialog": { @@ -80,6 +82,74 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Der \"~\"-Operator", + "", + "Nehem wir an du willst viele Schritte im Commit-Baum zurückgehen. Dann wird es schnell mühsam immer wieder `^` einzugeben; deswegen gibt es in Git den Tilde-Operator `~`.", + "", + "Der Tilde-Operator akzeptiert optional eine Zahl, mit der du angeben kannst vieviele Vorgänger zu zurückgehen willst. Keine Anzahl anzugeben bewirkt dasselbe wie `~1`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Geben wir mit `~` an wiviele Commits wir zurückgehen wollen" + ], + "afterMarkdowns": [ + "Peng! So einfach -- relative Referenzen sind super." + ], + "command": "git checkout HEAD~4", + "beforeCommand": "git commit; git commit; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Erzwungene Branches", + "", + "Du bist jetzt Experte in Sachen relative Referenzen, also lass sie uns mal richtig einsetzen.", + "", + "Das Verschieben von Branches ist einer der häufigsten Anwendungsfälle dafür. Du kannst einen Branchnamen direkt auf einen bestimmten Commit setzen (_ohne_ ihne vorher ausgecheckt haben zu müssen!) indem du den Parameter `-f` benutzt. So in etwa:", + "", + "`git branch -f master HEAD~3`", + "", + "Das bewegt (erzwungenermaßen) den `master` auf den Commit drei Vorgänger vor `HEAD`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns das mal in Aktion an:" + ], + "afterMarkdowns": [ + "Das war's schon! Relative Referenzen ermüglichen es uns den Commit `C1` sehr einfach anzugeben und `git branch -f` ermöglicht es uns, den Branch sehr schnell auf diesen Commit zu setzen." + ], + "command": "git branch -f master HEAD~3", + "beforeCommand": "git commit; git commit; git commit; git checkout -b bugFix" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Jetzt wo du relative Referenzen und erzwungenes Branching in Kombination gesehen hast können wir damit den nächsten Level bewältigen.", + "", + "Bewege `HEAD`, `master` und `bugFix` an die jeweils angegebenen Positionen, um diesen Level abzuschließen." + ] + } + } + ] + }, "zh_CN": { "childViews": [ { diff --git a/src/levels/rampup/reversingChanges.js b/src/levels/rampup/reversingChanges.js index ae6fecb1..6ac0303a 100644 --- a/src/levels/rampup/reversingChanges.js +++ b/src/levels/rampup/reversingChanges.js @@ -5,6 +5,7 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"pushed\":{\"target\":\"C2\",\"id\":\"pushed\"},\"local\":{\"target\":\"C3\",\"id\":\"local\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"local\",\"id\":\"HEAD\"}}", "name": { "en_US": "Reversing Changes in Git", + "de_DE": "Änderungen in Git rückgängig machen", "ja": "変更を元に戻す", "fr_FR": "Annuler des changements avec Git", "ko": "Git에서 작업 되돌리기", @@ -12,6 +13,7 @@ exports.level = { }, "hint": { "en_US": "Notice that revert and reset take different arguments.", + "de_DE": "Beachte, dass revert und reset unterschiedliche Argumente benötigen", "fr_FR": "", "zh_CN": "注意revert和reset使用不同的参数。", "ko": "", @@ -81,6 +83,69 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Änderungen in Git rückgängig machen", + "", + "Es gibt viele Möglichkeiten, Änderungen in Git zurückzunehmen. Und ebenso wie das Committen hat auch das rückgängig Machen eine Basis-Komponente (Dateien und Inhalte vormerken) und einen übergeordneten Aspekt (wie die Änderungen tatsächlich zurückgenommen werden). Diese Applikation beschäftigt sich wiederum mit den übergeordneten Vorgängen.", + "", + "Es gibt grundsätzlich zwei Arten in Git etwas rückgängig zu machen -- einerseits `git reset` und andererseit `git revert`. Wir schauen uns beide mal an.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Reset", + "", + "`git reset` nimm Änderungen zurück, indem es eine Branch-Referenz auf einen anderen Commit setzt. Es ist ein bisschen (aber nicht wirklich) wie \"Geschichte umschreiben\"; `git reset` bewegt einen Branch auf einen anderen Commit, als hätte er nie anders ausgesehen.", + "", + "Schauen wir, wie das aussieht:" + ], + "afterMarkdowns": [ + "Schick! Git hat den `master` einfach auf `C1` gesetzt; unser lokales Repository sieht nun so aus, als hätte `C2` nie stattgefunden." + ], + "command": "git reset HEAD~1", + "beforeCommand": "git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "## Git Revert", + "", + "Obwohl `git reset` super im lokalen Kontext funktioniert, ist der Ansatz vom \"Umschreiben\" der Commit-Geschichte nicht geeignet für Branches, die auf einem Server liegen und auch von anderen benutzt werden.", + "", + "Um Änderungen rückgängig zu machen und das mit anderen zu *teilen* müssen wir `git revert` benutzen. Schauen wir uns das in Aktion an." + ], + "afterMarkdowns": [ + "Komisch, es ist ein neuer Commit entstanden. Das liegt daran, dass `C2'` genau die *Änderungen* enthält, die die Änderungen aus `C2` aufheben.", + "", + "Durch Reverten kannst du das Zurücknehmen von Änderungen mit anderen teilen." + ], + "command": "git revert HEAD", + "beforeCommand": "git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level abzuschließen musst du sowohl auf `local` also auch auf `pushed` jeweils die zwei letzten Commits zurücknehmen.", + "", + "Vergiss nicht, dass `pushed` auch auf einem Server liegt und `local` ein rein lokaler Branch ist -- das sollte dir helfen, die richtige Methode zu wählen." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/rebase/manyRebases.js b/src/levels/rebase/manyRebases.js index 098d4594..49ec4334 100644 --- a/src/levels/rebase/manyRebases.js +++ b/src/levels/rebase/manyRebases.js @@ -9,12 +9,14 @@ exports.level = { "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"side\":{\"target\":\"C6\",\"id\":\"side\"},\"another\":{\"target\":\"C7\",\"id\":\"another\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C0\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C5\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { "en_US": "Rebasing over 9000 times", + "de_DE": "10000 Rebases unter dem `HEAD`", "ko": "9천번이 넘는 리베이스", "ja": "Rebasing over 9000 times", "zh_CN": "N次Rebase" }, "hint": { "en_US": "Remember, the most efficient way might be to only update master at the end...", + "de_DE": "Nicht vergessen: die effizienteste Möglichkeit könnte sein, schließlich einfach nur den master zu aktualisieren ...", "ja": "最も効率的なやり方はmasterを最後に更新するだけかもしれない・・・", "ko": "아마도 master를 마지막에 업데이트하는 것이 가장 효율적인 방법일 것입니다...", "zh_CN": "记住,最后更新master分支可能是最高效的方法。" @@ -38,6 +40,25 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Mehrere Branches rebasen", + "", + "Wow, wir haben hier ja eine Menge Branches! Lass uns mal die ganze Arbeit, die in diesen Branches steckt, auf den `master` packen, um sie auf Stand zu bringen.", + "", + "Die Führungsetage macht die Sache allerdings etwas trickreicher -- die möchten, dass alle Commits in aufsteigender Reihenfolge geordnet sind. Das heißt unser fertiger Baum sollte `C7` ganz unten haben, darüber `C6` und so weiter und so fort.", + "", + "Upper management is making this a bit trickier though -- they want the commits to all be in sequential order. So this means that our final tree should have `C7'` at the bottom, `C6'` above that, etc etc, etc all in order.", + "Wenn du irgendwo einen Fehler machst, benutz ruhig `reset` um wieder von vorne anzufangen oder `undo` um einen Schrit zurückzugehen. Schau dir die Lösung an und versuch es in weniger Schritten hinzubekommen, als die." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/remote/clone.js b/src/levels/remote/clone.js index 5d9d6a76..62d01f7d 100644 --- a/src/levels/remote/clone.js +++ b/src/levels/remote/clone.js @@ -2,10 +2,12 @@ exports.level = { "goalTreeString": '{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":"o/master"},"o/master":{"target":"C1","id":"o/master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"},"originTree":{"branches":{"master":{"target":"C1","id":"master","remoteTrackingBranchID":null}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"}},"HEAD":{"target":"master","id":"HEAD"}}}', "solutionCommand": "git clone", "name": { - "en_US": "Clone Intro" + "en_US": "Clone Intro", + "de_DE": "Clone Einführung" }, "hint": { - "en_US": "Just git clone!" + "en_US": "Just git clone!", + "de_DE": "Einfach git clone ausführen!" }, "startDialog": { "en_US": { @@ -64,6 +66,63 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Remotes", + "", + "Entfernte Repositorys sind nicht weiter kompliziert. In dieser Welt des Cloud Computings könnte man vielleicht glauben, dass hiter entfernten Git-Repositorys eine Menge Magie steckt, aber es sind einfach nur Kopien eines Repositorys auf einem anderen Rechner. Du kannst mit diesem Rechner typischerweise über das Internet kommunizieren, was es dir ermöglicht Commits hin und her zu schicken.", + "", + "Nichtsdestoweniger haben entfernte Repositorys eine Menge toller Eigenschaften:", + "", + "- Vor allem: sie sind ein Super-Backup! Lokale Git-Repositorys können deine Arbeitskopie ein jeden beliebigen früheren Zustand versetzen (wie du ja weißt), aber all diese Informationen liegen eben bei dir lokal. Wenn es Kopien von deinem Repository auf anderen Rechnern gibt, kannst du ruhig all deine Daten verlieren und trotzdem genau da weitermachen, wo du aufgehört hast.", + "", + "- Noch wichtiger: Remotes geben dem Entwicklen eine soziale Komponente! Wenn eine Kopie deines Projekts woanders liegt können deine Freunde sehr einfach etwas zu dem Projekt beitragen (oder sich deine neuesten Änderungen holen).", + "", + "Websites, die die Aktivitäten um diese entfernten Repositorys darstellen (wie [Github](https://github.com/) oder [Phabricator](http://phabricator.org/)) erfreuen sich zunehmender Beliebtheit, aber entfernte Repositorys sind _immer_ das Rückgrat fü diese Werkzeuge. Deshalb ist es wichtig, sie zu verstehen." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Der Befehl um ein Remote zu erstellen", + "", + "Bis jetzt hat sich Learn Git Branching darauf konzentriert, die Grundlagen der _lokalen_ Arbeit mit Repositorys zu vermitteln (Branche anlegen, zusammenführen, Rebasen etc). Jetzt wollen wir allerdings lernen mit entfernten Repositorys zu arbeiten und brauchen für die Level eine entsprechende Umgebung. Die schaffen wir mit `git clone`.", + "", + "In der Realität ist `git clone` eigentlich der Befehl, mit dem du eine _lokale_ Kopie eines _entfernten_ Repositorys erstellst (das zum Beispiel auf Github liegt). Wir benutzen diesen Befehl in Learn Git Branching allerdings ein wenig anders -- hier macht `git clone` tatsächlich eine Kopie von deinem lokalen Repository auf einem \"entfernten Server\". Klar, das ist eigentlich genau das Gegenteil von dem was der echte Befehl macht, aber es hilft den Zusammenhang zwischen Cloning und der Arbeit mit entfernten Repositorys herzustellen, also machen wir's einfach so.", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Fangen wir langsam an und schauen nur wie ein entferntes Repository in unserer Darstellung aussieht.", + "" + ], + "afterMarkdowns": [ + "Da ist es! Jetzt haben wir ein entferntes Repository unseres Projektes. Es sieht so aus wie das lokale, nur mit ein paar Änderungen in der Darstellung -- in späteren Leveln wirst du sehen, wie man Änderungen zwischen den Repositorys austauschen kann." + ], + "command": "git clone", + "beforeCommand": "" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level abzuschließen führ einfach `git clone` auf deinem bestehenden Repository aus. Alles weitere kommt in den nächsten Leveln." + ] + } + } + ] } } }; From a6a96569bf4127e50b16606035fbf24482071411 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Sat, 21 Dec 2013 11:46:46 +0100 Subject: [PATCH 10/47] More levels translated, only 9 more to go --- src/levels/rebase/selectiveRebase.js | 22 ++++ src/levels/remote/fetchRebase.js | 149 ++++++++++++++++++++++++- src/levels/remote/mergeManyFeatures.js | 28 ++--- src/levels/remote/push.js | 47 +++++++- src/levels/remote/pushArgs.js | 79 ++++++++++++- src/levels/remote/sourceNothing.js | 59 +++++++++- 6 files changed, 363 insertions(+), 21 deletions(-) diff --git a/src/levels/rebase/selectiveRebase.js b/src/levels/rebase/selectiveRebase.js index 2c220305..a8291731 100644 --- a/src/levels/rebase/selectiveRebase.js +++ b/src/levels/rebase/selectiveRebase.js @@ -9,11 +9,13 @@ exports.level = { "name": { "ko": "브랜치 스파게티", "en_US": "Branch Spaghetti", + "de_DE": "Branch-Spaghetti", "ja": "ブランチスパゲッティ", "zh_CN": "分支浆糊" }, "hint": { "en_US": "Make sure to do everything in the proper order! Branch one first, then two, then three", + "de_DE": "Stelle sicher, dass du alles in der richtigen Reihenfolge machst! Branche erst one, dann two, dann three.", "ja": "全て正しい順番で処理すること!oneが最初で、次がtwo、最後にthreeを片付ける。", "ko": "이 문제를 해결하는 방법은 여러가지가 있습니다! 체리픽(cherry-pick)이 가장 쉽지만 오래걸리는 방법이고, 리베이스(rebase -i)가 빠른 방법입니다", "zh_CN": "确保你是按照正确的顺序来操作!先操作分支 `one`, 然后 `two`, 最后才是 `three`" @@ -39,6 +41,26 @@ exports.level = { } ] }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Branch-Spaghetti", + "", + "Puh! Wir haben ein ganz schön schweres Ziel für dieses Level.", + "", + "Wir haben hier einen `master`, der ein paar Commits weiter ist als die Branche `one`, `two` und `three`. Aus welchem Grund auch immer müssen wir diese drei anderen Branches mit modifizierten Versionen der paar letzten Commits von `master` aktualisieren.", + "", + "Branch `one` benötigt eine Umsortierung und `C5` muss gelöscht werden. `two` muss nur umsortiert werden und `three` braucht nur einen Commit!", + "", + "Ich lass dich diese Aufgabe selbst lösen -- schau dir hinterher auf jeden Fall die Lösung mit `show solution` an." + ] + } + } + ] + }, "ja": { "childViews": [ { diff --git a/src/levels/remote/fetchRebase.js b/src/levels/remote/fetchRebase.js index 6d0f8881..a3282063 100644 --- a/src/levels/remote/fetchRebase.js +++ b/src/levels/remote/fetchRebase.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git clone;git fakeTeamwork;git commit;git pull --rebase;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { - "en_US": "Diverged History" + "en_US": "Diverged History", + "de_DE": "Abweichende History" }, "hint": { - "en_US": "check out the ordering from the goal visualization" + "en_US": "check out the ordering from the goal visualization", + "de_DE": "Beachte die Reihenfolge in der Zieldarstellung" }, "startDialog": { "en_US": { @@ -151,6 +153,149 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Abweichende Inhalte", + "", + "Bisher haben wir gesehen wie man per `pull` Commits von Anderen ins lokale Repository holt und die eigenen Änderungen in ein entferntes `push`t. Ist doch ziemlich einfach, wie kann man da durcheinander kommen?", + "", + "Die Schwierigkeiten entstehen, wenn die History der beiden Repositorys *divergieren*, also voneinander abweichen. Bevor wir die Einzelheiten besprechen, schauen wir uns ein Beispiel an ...", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Stellt dir vor du holst dir Montags ein Repository per `clone` und fängst an, an einem Feature zu arbeiten. Bis Freitag soll es fertig und veröffentlicht sein -- doch, oh je! Deine Kollegen haben eine Menge Code während der Woche geschrieben, der dein Feature hat veralten lassen (und überflüssig gemacht hat). Sie haben diesen Code außerdem zum entfernten Repository gepusht, und dadurch basiert *deine* harte Arbeit jetzt auf einer *alten* Version des Projektes, die nicht länger relevant ist.", + "", + "In diesem Fall ist ein `git push` problematisch. Wenn du es ausführst, soll Git das entfernte Repository in den Zustand von Montag zurückversetzen? Soll es versuchen deinen Code auf die aktuelle Version zu packen? Oder soll es deine Änderungen einfach ignorieren, weil sie total veraltet sind?", + "", + "Da es in dieser Situation so viele Mehrdeutigkeiten gibt (da die Historys divergent sind) erlaubt Git dir nicht, deine Änderungen einfach zu `push`en. Es zwingt dich, zuerst die neuesten Änderungen vom Server zu holen und in deine zu integrieren bevor du deine Arbeit mit anderen teilen kannst." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Bla bla bla. Schauen wir uns das lieber in Aktion an:" + ], + "afterMarkdowns": [ + "Siehst du? Nichts passiert, weil der Befehl fehlschlägt. `git push` schlägt fehl, weil der neueste Commit `C3` auf dem Commit `C1` auf dem Remote basiert. Der entfernte Server hat mittlerweile jedoch `C2` gepusht bekommen, also lässt Git deinen Push jetzt nicht mehr zu." + ], + "command": "git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wie sollen wir das auflösen? Es ist ganz einfach, du musst deinen Commit nur von der aktuellsten Version des Remotes ableiten.", + "", + "Es gibt verschiedene Möglichkeiten wie man das erreichen kann, aber die offensichtlichste ist es, deine Commits per Rebase zu verschieben. Schauen wir mal wie das abläuft:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Also wenn wir vor dem Push erst mal einen Rebase mache ..." + ], + "afterMarkdowns": [ + "Bämm! Wir haben unsere lokale Abbildung des entfernten Repositorys mit `git fetch` auf den neuesten Stand gebracht, unsere Arbeit auf die neueste Version des Remotes drauf gepackt und dann mit `git push` auf den Server geschoben." + ], + "command": "git fetch; git rebase o/master; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Gibt es noch weitere Möglichkeiten deine Arbeit zu aktualisieren wenn das entfernte Repository neue Commits bekommen hat? Klar! Schauen wir uns dasselbe an, aber diesmal arbeiten wir mit `merge`.", + "", + "Obwohl `git merge` deine Arbeit nicht verschiebt (und stattdessen einen Merge Commit erzeugt) ist es eine Möglichkeit Git dazu zu bringen, alle Änderungen vom Remote in deine Sachen zu integrieren. Denn durch den Merge wird der Remote Branch zu einem *Vorgänger* deines Branches, was bedeutet dass dein Commit alle Commits des entfernten Branches beinhaltet.", + "", + "Zur Demonstration ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Wenn wir nun also mergen anstatt einen Rebase zu machen ..." + ], + "afterMarkdowns": [ + "Ok. Wir haben die lokale Abbildung des entfernen Repositorys mit `git fetch` aktualisiert, die neuen Änderungen per *Merge* in deine integriert, und letztere dann mit `git push` auf den Server gebracht." + ], + "command": "git fetch; git merge o/master; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wahnsinn! Kann ich das auch irgendwie machen ohne soviel zu tippen?", + "", + "Na klar -- du kennst ja schon `git pull` als Zusammenfassung von `fetch` und `merge`. Praktischerweise bringt man es mit der Option `--rebase` dazu, anstatt des Merge einen Rebase zu machen.", + "", + "Gucken wir uns das mal an." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Zunächst `git pull --rebase` ..." + ], + "afterMarkdowns": [ + "Genau wie vorher! Nur viel kürzer." + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Und nun das normale `git pull` ..." + ], + "afterMarkdowns": [ + "Und wieder, genau wie zuvor!" + ], + "command": "git pull; git push", + "beforeCommand": "git clone; git fakeTeamwork; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Dieser Ablauf von `fetch`, `rebase` / `merge` und `push` ist sehr verbreitet. In zukünftigen Leveln werden wir uns kompliziertere Varianten dieses Workflows ansehen, aber jetzt probieren wir erst mal diesen aus.", + "", + "Um diesen Level zu lösen, gehe folgende Schritte durch:", + "", + "* Clone dein Repository", + "* Simuliere einen entfernten Commit mit `git fakeTeamwork`", + "* Erzeuge einen lokalen Commit", + "* Benutze *Rebase*, um deine Arbeit schließlich pushen zu können" + ] + } + } + ] } } }; diff --git a/src/levels/remote/mergeManyFeatures.js b/src/levels/remote/mergeManyFeatures.js index 86511576..8afeb1bd 100644 --- a/src/levels/remote/mergeManyFeatures.js +++ b/src/levels/remote/mergeManyFeatures.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git checkout master;git pull;git merge side1;git merge side2;git merge side3;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]},\"side1\":{\"target\":\"C2\",\"id\":\"side1\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side2\":{\"target\":\"C4\",\"id\":\"side2\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side3\":{\"target\":\"C7\",\"id\":\"side3\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"side3\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C8\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C8\":{\"parents\":[\"C1\"],\"id\":\"C8\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Merging with remotes" + "en_US": "Merging with remotes", + "de_DE": "Änderungen vom Remote zusammenführen" }, "hint": { - "en_US": "Pay attention to the goal tree!" + "en_US": "Pay attention to the goal tree!", + "de_DE": "Beachte den Ziel-Baum!" }, "compareOnlyMaster": true, "startDialog": { @@ -16,11 +18,11 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "## Why not merge?", + "## Warum nicht Merge?", "", - "In order to push new updates to the remote, all you need to do is *incorporate* the latest changes from the remote. That means you can either rebase *or* merge in the remote branch (e.g. `o/master`).", + "Um neue Dinge auf das Remote zu schieben musst du erst alle Änderungen vom Remote holen und bei dir integrieren. Das bedeutet du kannst den entfernten Branch (z.B. `o/master`) entweder Rebasen *oder* Mergen.", "", - "So if you can do either method, why have the lessons focused on rebasing so far? Why is there no love for `merge` when working with remotes?", + "Wenn du also beide Methoden benutzen kannst, warum haben sich die Level bisher auf Rebase konzentriert? Warum mag keiner `merge` wenn es um Remotes geht?", "" ] } @@ -29,19 +31,19 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Theres a lot of debate about the tradeoffs between merging and rebasing in the development community. Here are the general pros / cons of rebasing:", + "Es gibt eine Menge Diskussionen unter Entwicklern über die Vor- und Nachteile beim Mergen und Rebasen. Hier ein paar Vor- und Nachteile zum Rebasen:", "", - "Pros:", + "Vorteile:", "", - "* Rebasing makes your commit tree look very clean since everything is in a straight line", + "* Rebasen macht den Commit-Baum sehr übersichtlich, weil alles linear aufeinander aufbaut", "", - "Cons:", + "Nachteile:", "", - "* Rebasing modifies the (apparent) history of the commit tree.", + "* Rebasen verändert die History eines Branches.", "", - "For example, commit `C1` can be rebased *past* `C3`. It then appears that the work for `C1'` came after `C3` when in reality it was completed beforehand.", + "Zum Beispiel kann durch Rebasen Commit `C1` an Commit `C3` *vorbei* bewegt werden, bzw. eine Kopie von `C1`. Es sieht dann so aus als wären die Änderungen in `C1` nach denen in `C3` gemacht worden, obwohl das nicht stimmt.", "", - "Some developers love to preserve history and thus prefer merging. Others (like myself) prefer having a clean commit tree and prefer rebasing. It all comes down to preferences :D" + "Manche Entwickler möchten lieber die History lassen wie sie ist und ziehen daher das Mergen vor. Andere (wie ich) haben lieber einen sauberen Commit-Baum und ziehen Rebase vor. Am Ende ist es eine Geschmacksfrage. :D" ] } }, @@ -49,7 +51,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "For this level, let's try to solve the previous level but with *merging* instead. It may get a bit hairy but it illustrates the point well" + "In diesem Level wollen wir versuchen die Aufgabe vom letzten Level erneut zu lösen, aber diesmal mit einem *Merge*. Das wird vielleicht etwas haariger, stellt aber gut die Implikationen dar." ] } } diff --git a/src/levels/remote/push.js b/src/levels/remote/push.js index d2743f11..8e4d2a26 100644 --- a/src/levels/remote/push.js +++ b/src/levels/remote/push.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git clone;git commit;git commit;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { - "en_US": "Git Pushin'" + "en_US": "Git Pushin'", + "de_DE": "Git Push" }, "hint": { - "en_US": "Remember you have to clone before you can push!" + "en_US": "Remember you have to clone before you can push!", + "de_DE": "Denk dran, dass du einen Clone brauchst bevor du Pushen kannst!" }, "startDialog": { "en_US": { @@ -49,6 +51,47 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Push", + "", + "Nun hab ich also Änderungen vom entfernten Server geholt und in meine lokale Arbeit integriert. Das ist schön und gut ... aber wie teile ich _meine_ Wahnsinns-Entwicklungen mit allen anderen?", + "", + "Naja, das Hochladen von Zeug ist das Gegenteil zum Herunterladen von Zeug. Und was ist das Gegenteil von `git pull`? Genau, `git push`!", + "", + "`git push` ist dafür verantwortlich _deine_ Änderungen zu einem bestimmten entfernten Server hochzuladen und dort zu integrieren. Sobald das `git push` durch ist, können alle deine Freunde diese Änderungen zu sich herunterladen.", + "", + "Du kannst dir `git push` als einen Befehl zu \"Veröffentlichen\" deiner Arbeit vorstellen. Es gibt da noch ein paar Feinheiten, aber lass uns mal mit kleinen Schritten anfangen." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Hier haben wir ein paar Änderungen, die auf dem Remote noch fehlen. Und hoch damit!" + ], + "afterMarkdowns": [ + "Na bitte -- das Remote hat den Commit `C2` bekommen, der `master` auf dem Remote ist entsprechend aktualisiert worden und unsere *eigene* Abbildung des `master` auf dem Remote namens `o/master` wurde auch aktualisiert. Alles im Lot!" + ], + "command": "git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level zu schaffen musst du einfach nur zwei neue Commits auf das Remote bringen. Aber stell dich schon mal darauf ein, dass die nächsten Level anspruchsvoller werden!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pushArgs.js b/src/levels/remote/pushArgs.js index c3623aaa..287e4b78 100644 --- a/src/levels/remote/pushArgs.js +++ b/src/levels/remote/pushArgs.js @@ -6,10 +6,12 @@ exports.level = { "git checkout": true }, "name": { - "en_US": "Git push arguments" + "en_US": "Git push arguments", + "de_DE": "Optionen für Git Push" }, "hint": { - "en_US": "You can always look at the last slide of the dialog with \"objective\"" + "en_US": "You can always look at the last slide of the dialog with \"objective\"", + "de_DE": "Du kannst dir die Zielsetzung des Levels immer wieder mit \"objective\" anzeigen lassen" }, "startDialog": { "en_US": { @@ -83,6 +85,79 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Push arguments", + "## Push-Optionen", + "", + "Großartig! Da du dich jetzt mit Remote Tracking Branches auskennst können wir anfangen, die Geheimnisse hinter `git push`, `fetch` und `pull` zu ergründen. Wir werden uns einen Befehl nach dem anderen vornehmen, aber die Funktionsweisen sind sich sehr ähnlich.", + "", + "Zunächst schauen wir uns `git push` an. Du hast im Level über Remote Tracking schon mitbekommen, dass Git den Remot Server *und* den Branch herausbekommt, indem sich die Eigenschaften des aktuell ausgecheckten Branches ansieht (in denen das Remote steht, das der Branch \"trackt\"). Das ist das Verhalten bei keiner Angabe weiterer Optionen -- du kannst bei `git push` aber auch folgende setzen:", + "", + "`git push `", + "", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Was \"Ort\" sein soll fragst du? Das klären wir später genau, schauen wir uns zunächst ein Beispiel an:", + "", + "`git push origin master`", + "", + "Das bedeutet im Klartext:", + "", + "\"Geh zum Branch namens `master` in meinem Repository, nimm all seine Commits, dann geh zum Branch `master` auf dem Remote namens `origin`. Leg da alles Commits ab die fehlen und sag mir wenn du fertig bist.\"", + "", + "Dadurch, dass wir `master` als \"Ort\" angegeben haben, weiß Git *woher* die Commits kommen und *wohin* sie sollen. Es ist im Grunde der Name der Orte, die zwischen zwei Repositorys synchronisiert werden soll.", + "", + "Dadurch, dass wir Git alles explizit gesagt haben, was es für die Operation wissen muss (durch Angabe von Remote und Ort) ist es vollkommen egal, was gerade ausgecheckt ist." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns noch ein Beispiel an. Beachte was in diesem Fall gerade ausgecheckt ist." + ], + "afterMarkdowns": [ + "Da haben wir's! `master` wurde auf dem Remote aktualisiert, weil wir beide Optionen angegeben haben." + ], + "command": "git checkout C0; git push origin master", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Was wäre passiert, wenn wir keine Optionen benutzt hätten?" + ], + "afterMarkdowns": [ + "Der Befehl schlägt fehlt, da `HEAD` nicht auf einem Branch steht, der ein Remote trackt." + ], + "command": "git checkout C0; git push", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, in diesem Level lass und sowohl `foo` als auch `master` auf dem Remote aktualisieren. Um's spannender zu machen, ist `git checkout` in diesem Level deaktiviert." + ] + } + } + ] } } }; diff --git a/src/levels/remote/sourceNothing.js b/src/levels/remote/sourceNothing.js index 12161090..bd2d476d 100644 --- a/src/levels/remote/sourceNothing.js +++ b/src/levels/remote/sourceNothing.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git push origin :foo;git fetch origin :bar", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Source of nothing" + "en_US": "Source of nothing", + "de_DE": "Die Quelle des Nichts" }, "hint": { - "en_US": "The branch command is disabled for this level so you'll have to use fetch!" + "en_US": "The branch command is disabled for this level so you'll have to use fetch!", + "de_DE": "Der branch Befehl ist für diesen Level inaktiv, du musst also fetch benutzen" }, "startDialog": { "en_US": { @@ -61,6 +63,59 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Die Eigentümlichkeiten von ``", + "", + "Git \"missbraucht\" den ``-Parameter in zwei Fällen. Diese rühren daher, dass man technisch gesehen \"nichts\" als gültige `` sowohl für `git push` als auch für `git fetch` angeben kann. Das macht man so:", + "", + "* `git push origin :side`", + "* `git fetch origin :bugFix`", + "", + "Schauen wir, was das bewirkt ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Was passiert, wenn man \"nichts\" auf einen entfernten Branch pusht? Er wird gelöscht!" + ], + "afterMarkdowns": [ + "Und schon haben wir `foo` erfolgreich auf dem Remote gelöscht, weil wir \"Leere\" darauf geschoben haben. Ist auf seine Weise irgendwie logisch ..." + ], + "command": "git push origin :foo", + "beforeCommand": "git clone; git push origin master:foo" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Und weiter: indem man \"nichts\" von einem Remote in sein lokales Repository zieht, erstellt man tatsächlich einen neuen Branch." + ], + "afterMarkdowns": [ + "Ziemlich abgefahren / bizarr, aber was soll's. Das ist halt Git." + ], + "command": "git fetch origin :bar", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Das ist ein kurzer Level -- lösch einfach den Remote Branch und erstelle einen neuen Branch mit `git fetch`, um ihn zu lösen." + ] + } + } + ] } } }; From 33036a756e062e6f1092e77cae19232236daf5b3 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Sat, 21 Dec 2013 16:17:07 +0100 Subject: [PATCH 11/47] More translations; five to go --- src/levels/remote/fakeTeamwork.js | 60 ++++++++++++- src/levels/remote/fetchArgs.js | 130 +++++++++++++++++++++++++++- src/levels/remote/remoteBranches.js | 67 +++++++++++++- src/levels/remote/tracking.js | 118 ++++++++++++++++++++++++- 4 files changed, 367 insertions(+), 8 deletions(-) diff --git a/src/levels/remote/fakeTeamwork.js b/src/levels/remote/fakeTeamwork.js index 978879cd..72015d16 100644 --- a/src/levels/remote/fakeTeamwork.js +++ b/src/levels/remote/fakeTeamwork.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git clone;git fakeTeamwork 2;git commit ;git pull", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", "name": { - "en_US": "Faking Teamwork" + "en_US": "Faking Teamwork", + "de_DE": "Teamarbeit simulieren" }, "hint": { - "en_US": "remember you can specify the number of commits to fake" + "en_US": "remember you can specify the number of commits to fake", + "de_DE": "Nicht vergessen, du kannst angeben wieviele Commits simuliert werden sollen." }, "startDialog": { "en_US": { @@ -62,6 +64,60 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Zusammenarbeit simulieren", + "", + "Hier ist das Problem -- für einige der folgenden Level müssen wir lernen, wie man Änderungen vom entfernten Server holt.", + "", + "Das heißt wir müssen im Grunde \"so tun\" also ob der Server von einem Kollegen / Freund / Mitarbeiter aktualisiert worden wäre, manchmal ein bestimmter Branch oder eine bestimmte Anzahl von Commits.", + "", + "Um das zu tun führen wir den passend benannten Befehl `git fakeTeamwork` ein! Er ist ziemlich selbsterklärend, schauen wir uns ihn an ..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Das normale Verhalten von `fakeTeamwork` ist es, einen Commit auf den entfernten `master` zu machen." + ], + "afterMarkdowns": [ + "Da haben wir's -- der Server ist mit einem neuen Commit aktualisiert worden und wir haben ihn noch nicht lokal, weil wir nicht `git fetch` oder `git pull` ausgeführt haben." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Du kannst auch angeben wieviele Commits oder auf welchem Branch sie gemacht werden sollen, indem du das an den Befehl anhängst." + ], + "afterMarkdowns": [ + "Mit einem Befehlt haben wir simuliert, dass ein Kollege drei Commits auf den Branch `foo` gepackt hat." + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Die kommenden Level werden recht anspruchsvoll, daher verlangen wir auch in diesem Level schon etwas mehr.", + "", + "Leg log und erstelle ein Remote (mit `git clone`), simuliere ein paar Änderungen auf dem Server, committe lokal und dann zieh dir die Änderungen vom Server. Das ist wie mehrere Level in einem!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/fetchArgs.js b/src/levels/remote/fetchArgs.js index 56206a4d..d6bb7850 100644 --- a/src/levels/remote/fetchArgs.js +++ b/src/levels/remote/fetchArgs.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git fetch origin master~1:foo;git fetch origin foo:master;git checkout foo;git merge master", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"C1\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C6\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Fetch arguments" + "en_US": "Fetch arguments", + "de_DE": "Optionen für Fetch" }, "hint": { - "en_US": "Pay attention how the commit ids may have swapped! You can read slides again with \"help level\"" + "en_US": "Pay attention how the commit ids may have swapped! You can read slides again with \"help level\"", + "de_DE": "Beachtw wie die Commit IDs getauscht wurden! Du kannst den Einführungsdialog mit \"help level\" erneut anzeigen" }, "startDialog": { "en_US": { @@ -131,6 +133,130 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Fetch Optionen", + "", + "Nun haben wir also alles über `git push` Optionen gelernt, diesen coolen ``-Parameter, and sogar über mit Doppelpunkt getrennte Ref-Spezifikationen (`:`). Können wir all dieses neu erworbene Wissen auch auf `git fetch` anwenden?", + "", + "Jede Wette! Die Optionen für `git fetch` sind wirklicht *sehr, sehr* ähnlich denen von `git push`. Es sind dieselben Verfahren, nur in die andere Richtung angewendet (da man bei `fetch` herunterlädt anstatt hochzuladen).", + "", + "Gehen wir die verschiedenen Verfahrensweise mal eine nach der anderen durch ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Der Parameter ``", + "", + "Wenn du, wie folgt, einen \"Ort\" bei `git fetch` angibst:", + "", + "`git fetch origin foo`", + "", + "wird Git zum Branch `foo` auf dem Remote gehen, dort alle Änderungen holen, die es lokal noch nicht gibt, und sie an den lokalen Branch `o/foo` anhängen.", + "", + "Schauen wir uns das mal live an (nur zur Wiederholung)" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Durch Angabe eines Ortes ..." + ], + "afterMarkdowns": [ + "... laden wir die fehlenden Commits von `foo` und packen sie auf `o/foo` drauf", + "We download only the commits from `foo` and place them on `o/foo`" + ], + "command": "git fetch origin foo", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Du wunderst dich vielleicht warum Git diese Commits auf den `o/foo` Branch gepacht hat, anstatt einfach direkt auf den lokalen Branch `foo`? Zeigt der Parameter `` nicht einen Ort an, der sowohl lokal als auch entfernt existiert?", + "", + "Nun ja, Git geht diesen Schritt weil du auf `foo` ja noch Commits haben könntest, die nicht auf dem Server sind, und da will es nichts durcheinander bringen. Ähnlich wie beim früheren Level zu `git fetch` -- es aktualisiert nicht deine Lokalen Arbeits-Branches, es lädt die Commits nur in die `o` (bzw. `origin`) Branches, damit du sie dir in Ruhe anschauen und integrieren kannst.", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Wenn das so ist, was passiert dann wenn ich explizit Quelle und Ziel im Ort angebe?", + "", + "Wenn du Commits wirklich per `fetch` *direkt* auf einen lokalen Branch holen willst, dann, ja, kannst du das mit einer Ref-Spezifikation erreichen. Das funktioniert nicht mit deinem gerade ausgecheckten Branch, aber davon abgesehen lässt Git es zu.", + "", + "Nur ein Haken -- `` bezeichnet jetzt einen Ort auf dem *entfernten* Server und `` ist ein *lokaler* Ort, wo die Commits hin sollen. Es ist genau umgekehrt wie bei `git push` und das ist logisch, denn wir übertragen die Daten ja auch in die umgekehrte Richtung!", + "", + "Davon abgesehen benutzt man das in der Praxis kaum. Ich zeige das vor allem um zu verdeutlichen, wie `fetch` und `push` sehr ähnlich sind, nur in entgegengesetzten Richtungen." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns den Quatsch mal in Aktion an:" + ], + "afterMarkdowns": [ + "Wow! Siehst du, git löst `foo~1` als Ort auf dem Server `origin` auf und lädt dessen Commits herunter in `bar` hinein. Beachte wie `foo` und `o/foo` *nicht* aktualisiert wurden, da wir ein Ziel angegeben haben." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Was ist denn wenn das Ziel nicht existiert, für das ich den Befehl ausführe? Schauen wir uns das letzte Beispiel noch mal an, nur dass `bar` jetzt noch nicht existiert." + ], + "afterMarkdowns": [ + "Siehst du, es ist *genau* wie `git push`. Git erstellt das Ziel lokal bevor es den `fetch` ausführt, genauso wie Git erst das Ziel auf dem Remote erstellt, befor es pusht (falls das Ziel nicht existiert)." + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Keine Optionen?", + "", + "Wenn bei `git fetch` keine Optionen angegeben werden, lädt es einfach alle Commits vom Remote auf die lokalen Abbildungen aller Remote Branches ..." + ], + "afterMarkdowns": [ + "Ziemlich einfach, aber man sollte es mal gesehen haben." + ], + "command": "git fetch", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, genug gelabert! Um den Level zu schaffen musst du nur die im Zielbild angegebenen Commits per `fetch` holen. Sei kreativ mit den Befehlen!", + "", + "Du wirst Quelle und Ziel bei beiden `fetch` Befehlen angeben müssen. Schau dir das Zielbild gut an, da die IDs vertauscht sein könnten!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/remoteBranches.js b/src/levels/remote/remoteBranches.js index 60d2af01..948fe462 100644 --- a/src/levels/remote/remoteBranches.js +++ b/src/levels/remote/remoteBranches.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git commit;git checkout o/master;git commit", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Remote Branches" + "en_US": "Remote Branches", + "de_DE": "Branches auf entfernten Servern" }, "hint": { - "en_US": "Pay attention to the ordering -- commit on master first!" + "en_US": "Pay attention to the ordering -- commit on master first!", + "de_DE": "Beachte die Sortierung -- committe zuerst auf dem master!" }, "startDialog": { "en_US": { @@ -69,6 +71,67 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Branches auf entfernten Servern", + "", + "Nun da du `git clone` in Aktion gesehen hast, lass uns tiefer in die Materie eintauchen.", + "", + "Das erste, was dir wahrscheinlich aufgefallen ist, ist dass ein neuer Branch in unserem lokalen Repository aufgetaucht ist, namens `o/master`. Diese Art von Branch nennt sich _Remote_ Branch; er hat besondere Eigenschaften, weil er einem bestimmten Zweck dient.", + "", + "Ein Remote Branch bildet den Zustand des entsprechenden Branch in einem entfernten Repository ab (dem Zustand in dem der Branch war, als du das letzte mal das entfernte Repository angesprochen hast). Er hilft dir, den Unterschied zwischen deinem lokalen Branch und dem Gegenstück auf dem Server zu sehen -- eine nötige Information, bevor du deine Arbeit mit anderen teilen kannst.", + "", + "Remote Branches besitzen die besondere Eigenschaft dein Repository in den \"Detached `HEAD`\" Zustand zu versetzen, wenn du sie auscheckst. Git macht das absichtlich so, denn du kannst nicht direkt auf Remote Branches arbeiten; du musst auf Kopien von ihnen arbeiten und deine Änderungen von dort auf den entfernten Server schieben (wonach der Remote Branch dann auch bei dir aktualisiert wird)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Was heißt `o/`?", + "", + "Du fragst dich vielleicht was das `o/` am Anfang des Namens des Remote Branch bedeuten soll. Nun, Remote Branches folgen einer (zwingenden) Namenskonvention -- sie werden mit diesem Format gebildet:", + "", + "* `/`", + "", + "Wenn du also einen Remote Branch namens `o/master` hast, ist es eine Abbildung des Branches `master` auf dem Server, der in deinem Repository als `origin` bekannt ist.", + "", + "Die meisten Entwickler nennen das Haupt-Remote tatsächlich `origin` und nicht `o`. Das ist so verbreitet, dass Git den entfernten Server von dem man ein `git clone` macht tatsächlich als `origin` im Clone speichert.", + "", + "Leider passt der ganze Name, `origin`, nicht in unsere Darstellung, deshalb benutzen wir hier kurz `o`. :( Merk dir einfach: wenn du echtes Git benutzt werden die Remotes meistens `origin` heißen!", + "", + "So, das war eine Menge zu verdauen, schauen wir uns das in Aktion an." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Checken wir mal einen Remote Branch aus und schauen was passiert" + ], + "afterMarkdowns": [ + "Wie du siehst setzt uns Git in den \"Detached `HEAD`\" Modus und aktualisiert dann nach dem Commit nicht den Branch `o/master`. Das liegt daran, dass der Remote Branch nur aktualisiert wird, wenn sich der entsprechende Branch auf dem Remote verändert." + ], + "command": "git checkout o/master; git commit", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level zu bewältigen musst du einen Commit in `master` machen und einen nachdem du `o/master` ausgecheckt hast. Das illustriert noch einmal wie sich Branches und Remote Branches unterschiedlich verhalten und dass letztere sich nur verändern, wenn sich ihr Zustand auf dem entfernten Server ändert." + ] + } + } + ] } } }; diff --git a/src/levels/remote/tracking.js b/src/levels/remote/tracking.js index e870e229..d47e47fd 100644 --- a/src/levels/remote/tracking.js +++ b/src/levels/remote/tracking.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git checkout -b side o/master;git commit;git pull --rebase;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Remote Tracking" + "en_US": "Remote Tracking", + "de_DE": "Remote Tracking" }, "hint": { - "en_US": "Remember there are two ways to set remote tracking!" + "en_US": "Remember there are two ways to set remote tracking!", + "de_DE": "Nicht vergessen, es gibt zwei Arten Remote Tracking einzurichten!" }, "startDialog": { "en_US": { @@ -124,6 +126,118 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Remote Tracking Branches", + "", + "In den letzten paar Leveln wirkte es womöglich etwas \"magisch\", dass Git automatisch wusste, dass der Branch `master` irgendwie mit `o/master` verwandt ist. Klar, sie haben ähnliche Namen und daher mag es logisch erscheinen sie in Verbindung zu bringen, aber offensichtlich wird es in zwei Szenarien:", + "", + "* Beim `pull` werden Commits in `o/master` heruntergeladen und dann per *Merge* in den Branch `master` gebracht. Aus der Verbindung zwischen den beiden Branches leitet sich das Ziel des Merges ab.", + "* Beim `push` werden Commits vom `master` auf den `master` auf dem Remote Server geschoben (und die Änderung _danach_ in `o/master` abgebildet). Das *Ziel* des Push wird aus der Verbindung zwischen `master` und `o/master` abgeleitet.", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Langer Rede kurzer Sinn, die Verbindung zwischen `master` und `o/master` ist einfach die Eigenschaft des \"Remote Tracking\" dieser Branches. `master` ist so eingestellt, dass er `o/master` trackt -- das heißt es gibt ein implizites Ziel für `pull` und `push` Operationen auf dem `master` Branch.", + "", + "Du fragst dich vielleicht wieso diese Eigenschaft auf dem `master` definiert ist, wenn du das doch gar nicht explizit gemacht hast. Naja, beim Clonen eines Repository macht Git das für den `master` automatisch.", + "", + "Während des Clonens erstellt Git einen Remote Branch für jeden Branch, den es auf dem Remote Server findet (also Branches wie `o/master`); dann erstellt es für den Branch, auf den auf dem entfernten Server `HEAD` zeigt (meistens `master`) automatisch einen lokalen Branch und stellt ihn so ein, dass er sein Gegenstück auf dem Server trackt. Deswegen hast du beim clonen vielleicht schon mal dies gesehen:", + "", + " local branch \"master\" set to track remote branch \"o/master\"" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Kann ich das auch selbst machen?", + "", + "Na klar! Du kannst jeden beliebigen Branch so einstellen, dass er `o/master` trackt, und wenn du das tust wird der Branch dieselben impliziten Zielangaben für `push` und `pull` haben wie `master`. Du kannst also `git push` auf dem Branch `absolut_nicht_master` ausführen und deine Commits auf `master` auf dem entfernten Server schieben lassen.", + "", + "Es gibt zwei Möglichkeiten diese Eigenschaft zu definieren. Die erste ist, einen neuen lokalen Branch von einem Remote Branch auszuchecken. Wenn man", + "", + " git checkout -b absolut_nicht_master o/master", + "", + "eingibt, wir ein neuer lokaler Branch namens `absolut_nicht_master` angelegt, der `o/master` trackt." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Genug gequatscht, schauen wir uns eine Demonstration an! Wir checken einen neuen Branch `foo` aus, so dass er `master` auf dem Server trackt." + ], + "afterMarkdowns": [ + "Wie du siehst benutzen wir der implizite Ziel beim `pull` um `foo` zu aktualisieren. Beachte, dass `master` nicht aktualisiert wird." + ], + "command": "git checkout -b foo o/master; git pull", + "beforeCommand": "git clone; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Das gilt auch für `git push`." + ], + "afterMarkdowns": [ + "Bämm. Wir haben unsere Commits auf den `master` auf dem Server geschoben, obwohl unser lokale Branch völlig anders heißt." + ], + "command": "git checkout -b foo o/master; git commit; git push", + "beforeCommand": "git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Methode 2", + "", + "Noch eine Möglichkeit um Remote Tracking auf einem Branch einzustellen, ist einfach `git branch -u` zu benutzen. Wenn man", + "", + " git branch -u o/master foo", + "", + "eingibt, wir damit der lokale Branch `foo` so eingestellt, dass er `o/master` trackt. Den Namen des lokalen Branch kannst du auch weglassen, falls du ihn eh aktuell ausgecheckt hast:", + "", + " git branch -u o/master", + "" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns auch diese Meethode noch an ..." + ], + "afterMarkdowns": [ + "Genau wie vorher, nur ein bisschen ausführlicherer Befehl. Schick!" + ], + "command": "git branch -u o/master foo; git commit; git push", + "beforeCommand": "git clone; git checkout -b foo" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok. In diesem Level muss du Commits auf den `master` auf dem Server schieben, *ohne* den lokalen `master` ausgecheckt zu haben. Den Rest kannst du selbst herausfinden, schließlich ist das hier für Fortgeschrittene. :P" + ] + } + } + ] } } }; From 1082b2971de35dbd0b2821f7981cb4290048624f Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Sat, 21 Dec 2013 22:46:49 +0100 Subject: [PATCH 12/47] Finished translating levels --- src/levels/remote/fetch.js | 79 +++++++++++++++++++++++++- src/levels/remote/pull.js | 65 +++++++++++++++++++++- src/levels/remote/pullArgs.js | 80 ++++++++++++++++++++++++++- src/levels/remote/pushArgs2.js | 76 ++++++++++++++++++++++++- src/levels/remote/pushManyFeatures.js | 59 +++++++++++++++++++- 5 files changed, 349 insertions(+), 10 deletions(-) diff --git a/src/levels/remote/fetch.js b/src/levels/remote/fetch.js index 6c799afa..c985a17c 100644 --- a/src/levels/remote/fetch.js +++ b/src/levels/remote/fetch.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git fetch", "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"o/master\":{\"target\":\"C2\",\"id\":\"o/master\"},\"o/bugFix\":{\"target\":\"C3\",\"id\":\"o/bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C7\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C3\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Git Fetchin'" + "en_US": "Git Fetchin'", + "de_DE": "Git Fetch" }, "hint": { - "en_US": "just run git fetch!" + "en_US": "just run git fetch!", + "de_DE": "Einfach git fetch ausführen!" }, "startDialog": { "en_US": { @@ -81,6 +83,79 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Fetch", + "", + "In Git mit entfernten Repositorys zu arbeiten lässt sich wirklich auf das Hin- und Zurückübertragen von Daten reduzieren. Solange wir Commits hin und her schicken können, können wir jede Art Update teilen, das von Git getrackt wird (und somit Arbeit, neue Dateien, neue Ideen, Liebesbriefe etc. teilen).", + "", + "In diesem Level werden wir lernen, wie man Daten _von_ einem entfernten Repository holt -- der entsprechende Befehl heißt praktischerweise `git fetch`.", + "", + "Dir wird auffallen, dass sich mit der Aktualisierung unserer Darstellung des entfernten Repositorys die _Remote_ Branches auf den neuesten Stand gebracht werden. Das passt zum vorherigen Level über Remote Branches." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Bevor wir uns die Einzelheiten von `git fetch` ansehen wollen wir es mal in Aktion sehen. Wir haben hier ein entferntes Repository, das zwei Commits hat die in unserem lokalen Repository fehlen." + ], + "afterMarkdowns": [ + "Das war's! Die Commits `C2` und `C3` wurden zu unserem Repository heruntergeladen und unser Remote Branch `o/master` wurde aktualisiert." + ], + "command": "git fetch", + "beforeCommand": "git clone; git fakeTeamwork 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Was Fetch tut", + "", + "`git fetch` führt genau zwei Schritte aus:", + "", + "* Es lädt die Commits herunter, die im lokalen Repository fehlen, und ...", + "* aktualisiert die Remote Branches wo nötig (zum Beispiel, `o/master`).", + "", + "`git fetch` synchronisiert im Prinzip unsere _lokale_ Abbildung des entfernten Repositorys mit dem wie das entfernte Repository _tatsächlich_ aussieht (in diesem Moment).", + "", + "Wie du dich vielleicht erinnerst, haben wir im letzten Level gesagt, dass die Remote Branches den Zustand der Branches auf dem entfernten Repository darstellen _seit_ du das letzte Mal dieses Repository angesprochen hast. `git fetch` ist die Methode mit der du das Repository ansprichst! Der Zusammenhang zwischen Remote Branches und `git fetch` ist damit hoffentlich klar.", + "", + "`git fetch` kommuniziert mir dem entfernten Repository in der Regel über das Internet (über ein Protokoll wie `http://` oder `git://`).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### Was Fetch nicht tut", + "", + "`git fetch` ändert allerdings überhaupt nichts an _deinen_ lokalen Branches. Es aktualisiert nicht deinen `master` oder ändert irgendetwas an deinem Checkout.", + "", + "Das ist wichtig zu wissen, denn eine Menge Entwickler glauben, wenn sie `git fetch` ausführen würden ihre lokalen Branches auf den Stand des entfernten Repositorys gebracht. Es lädt zwar alle Daten herunter, damit man diese Aktualisierung durchführen kann, aber es ändert _nichts_ an deinen lokalen branches. Wir werden in späteren Level Befehle genau dafür kennenlernen. :D", + "", + "Am Ende des Tages kannst du dir `git fetch` also als den Donwload-Schritt vorstellen." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um diesen Level zu schaffen musst du einfach nur `git fetch` ausführen, um alle Commits herunterzuladen!" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pull.js b/src/levels/remote/pull.js index a5246d10..3adefabd 100644 --- a/src/levels/remote/pull.js +++ b/src/levels/remote/pull.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git pull", "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Git Pullin'" + "en_US": "Git Pullin'", + "de_DE": "Git Pull" }, "hint": { - "en_US": "Just run git pull!" + "en_US": "Just run git pull!", + "de_DE": "Führe einfach git pull aus." }, "startDialog": { "en_US": { @@ -67,6 +69,65 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Jetzt, wo wir wissen wie wir mit `git fetch` Daten von einem entfernten Repository holen können, wollen wir unsere lokalen Daten aktualisieren, damit sie die Änderungen vom Server beinhalten.", + "", + "Tatsächlich gibt es eine Menge Wege dies zu erreichen -- sobald du die neuen Commits lokal verfügbar hast, kannst du sie integrieren so als wären es Commits von ganz normalen anderen Branches. Du kannst also:", + "", + "* `git cherry-pick o/master`", + "* `git rebase o/master`", + "* `git merge o/master`", + "* usw. usf. ausfúhren.", + "", + "Der Ablauf, die Änderungen vom Server zu holen und dann in die eigene Arbeit zu mergen wird so häufig benötigt, dass Git einen Befehl kennt der beides auf einmal erledigt! Das ist `git pull`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns erst mal ein `fetch` gefolgt von `merge` an:" + ], + "afterMarkdowns": [ + "Bämm -- wir haben `C3` mit `fetch` heruntergeladen und dann in unseren Branch mit `git merge o/master` integriert. Nun bildet unser `master` dieselben Inhalte ab, wie sie auf dem entfernten Server (`origin`) liegen." + ], + "command": "git fetch; git merge o/master", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Was passiert wohl, wenn wir stattdessen `git pull` benutzen?" + ], + "afterMarkdowns": [ + "Exakt dasselbe! Das sollte recht deutlich machen, dass `git pull` nur eine Abkürzung für `git fetch` gefolgt von einem Merge des gerade aktualisierten Branches ist." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Die Feinheiten von `git pull` werden wir uns später ansehen, für's Erste lass es uns in diesem Level ausprobieren.", + "", + "Vergiss nicht -- du kannst diesen Level auch mit `fetch` und `merge` lösen, aber das kostet dich einen Befehl extra. :P" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pullArgs.js b/src/levels/remote/pullArgs.js index f3a670c7..7223f570 100644 --- a/src/levels/remote/pullArgs.js +++ b/src/levels/remote/pullArgs.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git pull origin bar:foo;git pull origin master:side", "startTree": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/bar\":{\"target\":\"C1\",\"id\":\"o/bar\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"bar\":{\"target\":\"C3\",\"id\":\"bar\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"bar\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Pull arguments" + "en_US": "Pull arguments", + "de_DE": "Optionen für Pull" }, "hint": { - "en_US": "Remember that you can create new local branches with fetch/pull arguments" + "en_US": "Remember that you can create new local branches with fetch/pull arguments", + "de_DE": "Du kannst neue lokale Branches mittels fetch / pull erstellen" }, "startDialog": { "en_US": { @@ -82,6 +84,80 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Optionen für Git Pull", + "", + "Da du jetzt so ziemlich *alles* kennst, was es an Optionen für `git fetch` und `git push` gibt, ist kaum noch etwas zu Optionen für `git pull` zu sagen. :)", + "", + "Das liegt daran, dass `git pull` letztendlich *wirklich* nur eine Abkürzuung für `fetch` gefolgt von einem `merge` von was auch immer gerade heruntergeladen wurde, ist. Denk es dir als ein `git fetch` mit denselben Optionen und einem anschließenden Merge.", + "", + "Das trifft sogar zu, wenn du völlig abgedrehte Optionen verwendest. Ein paar Beispiele:" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Hier sind einige gleichwertige Befehle in Git:", + "", + "`git pull origin foo` ist dasselbe wie:", + "", + "`git fetch origin foo; git merge o/foo`", + "", + "Unde ...", + "", + "`git pull origin bar~1:bugFix` ist dasselbe wie:", + "", + "`git fetch origin bar~1:bugFix; git merge bugFix`", + "", + "Siehst du? `git pull` ist wirklich nur eine Abkürzung von `fetch` + `merge` und es interessiert sich nur dafür wo die Commits hin sollen (die \"Ziel\"-Option, die es beim `fetch` auswertet).", + "", + "Schauen wir uns eine Demonstration an:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Wenn wir den Ort, auf den das `fetch` ausgeführt werden soll, angeben, passiert alles so wie beim `git fetch` aber es wird direkt danach auch ein Merge ausgeführt." + ], + "afterMarkdowns": [ + "Siehst du? Da wir `master` angegeben haben sind die Commits in `o/master` heruntergeladen worden. Danach wurde `o/master` gemerged, egal was gerade ausgecheckt war." + ], + "command": "git pull origin master", + "beforeCommand": "git clone; go -b bar; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Funktionniert das auch wenn man Quelle und Ziel angibt? Aber sicher! Das sehen wir hier:" + ], + "afterMarkdowns": [ + "Wow, das ist eine Menge in einem einzelnen Befehl. Wir haben lokal einen neuen Branch namens `foo` erstellt, die Commits vom `master` des Servers dorthin heruntergeladen und ihn danach in unseren aktuell ausgecheckten Commit `bar` gemerged." + ], + "command": "git pull origin master:foo", + "beforeCommand": "git clone; git fakeTeamwork; go -b bar; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, um's zu Ende zu bringen versuch das Ziel aus der Zielgrafik zu erreichen. Du wirst einige Commits herunterladen, einige neue Branches anlegen und diese in andere mergen müssen, aber das sollte nicht allzuviele Befehle benötigen. :P" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pushArgs2.js b/src/levels/remote/pushArgs2.js index 92fd5202..fea6c20c 100644 --- a/src/levels/remote/pushArgs2.js +++ b/src/levels/remote/pushArgs2.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git push origin master^:foo;git push origin foo:master", "startTree": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C4\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C2\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "name": { - "en_US": "Git push arguments -- Expanded!" + "en_US": "Git push arguments -- Expanded!", + "de_DE": "Optionen fü Git Push -- noch mehr!" }, "hint": { - "en_US": "Remember you can admit defeat and type in \"show solution\" :P" + "en_US": "Remember you can admit defeat and type in \"show solution\" :P", + "de_DE": "Vergiss nicht dass du aufgeben kannst, indem du \"show solution\" eingibst :P" }, "startDialog": { "en_US": { @@ -78,6 +80,76 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Details zum ``-Parameter", + "", + "Du erinnerst dich von dem vorherigen Level, dass, als wir `master` als \"Ort\" beim `git push` angegeben haben, daraus sowohl die *Quelle* als auch das *Ziel* für die Operation abgeleitet wurden.", + "", + "Daher fragst du dich vielleicht -- was wenn wir möchten, dass Quelle und Ziel ander sind? Was wenn du Commits von einem lokalen Branch `foo` in den Branch `bar` auf einem Server schieben möchtest?", + "", + "Tja, leider ist das in Git unmöglich .... ein Scherz! Natürlich ist das möglich. Git besitzt tonnenweise Flexibilität (eher zuviel, als zuwenig).", + "", + "Und gleich sehen wir, wie das geht ..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um sowohl Quelle als auch Ziel im ``-Parameter anzugeben, gib sie einfach verbunden mit einem Doppelpunkt ein:", + "", + "`git push origin :`", + "", + "Das wird üblicherweise Refspec (Referenz-Spezifikation) genannt. Refspec ist nur ein anderer Name für einen Ort, mit dem Git etwas anfangen kann (wie mit Branch `foo` oder mit `HEAD~2`)", + "", + "Sobald du Quelle und Ziel separat angibt, kannst du flexibel und präzise entfernte Branches ansteuern. Hier eine Demo:" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Vergiss nicht, `Quelle` ist jeder mögliche Ort, mit dem Git etwas anfangen kann:" + ], + "afterMarkdowns": [ + "Boah! Das ist ein ziemlich abgefahrener Befehl gewesen, aber er ist sinnvoll -- Git hat `foo^` zu einem Commit aufgelöst, alle Commits die bis zu diesem einschließich noch nicht auf dem Server waren hochgeladen und dann dort das Ziel aktualisiert." + ], + "command": "git push origin foo^:master", + "beforeCommand": "git clone; go -b foo; git commit; git commit" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Was wäre wenn das Ziel des `push` gar nicht existiert? Kein Problem! Wenn das Ziel ein Branch-Name ist, wird Git den Branch auf dem Server einfach anlegen." + ], + "afterMarkdowns": [ + "Schick, das ist ziemlich praktisch. :D" + ], + "command": "git push origin master:newBranch", + "beforeCommand": "git clone; git commit" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Um dieses Level zu schaffen versuch den dargestellten Zielzustand zu erreichen und vergiss nicht das Format:", + "", + "`:`" + ] + } + } + ] } } }; diff --git a/src/levels/remote/pushManyFeatures.js b/src/levels/remote/pushManyFeatures.js index 0d44b5bd..b6dd4d2d 100644 --- a/src/levels/remote/pushManyFeatures.js +++ b/src/levels/remote/pushManyFeatures.js @@ -3,10 +3,12 @@ exports.level = { "solutionCommand": "git fetch;git rebase o/master side1;git rebase side1 side2;git rebase side2 side3;git rebase side3 master;git push", "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]},\"side1\":{\"target\":\"C2\",\"id\":\"side1\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side2\":{\"target\":\"C4\",\"id\":\"side2\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null},\"side3\":{\"target\":\"C7\",\"id\":\"side3\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"side3\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C8\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C8\":{\"parents\":[\"C1\"],\"id\":\"C8\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "hint": { - "en_US": "Remember you can always use the undo or reset commands" + "en_US": "Remember you can always use the undo or reset commands", + "de_DE": "Denk dran, du kannst immer undo oder reset benutzen, um deine Befehle zurück zu nehmen." }, "name": { - "en_US": "Push Master!" + "en_US": "Push Master!", + "de_DE": "Push Master!" }, "compareOnlyMasterHashAgnostic": true, "startDialog": { @@ -62,6 +64,59 @@ exports.level = { } } ] + }, + "de_DE": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Einen Feature Branch reintegrieren", + "", + "Nun da du mit `fetch`, `pull`, und `push` vertraut bist sollten wir diese Fähigkeiten mit einem neuen Arbeitsablauf auf die Probe stellen.", + "", + "Für Entwickler in großen Projekten ist es nicht ungewöhnlich ihre Arbeit in Feature Branches (von `master` abgeleitet) zu erledigen und dann diese Inhalte zu reintegrieren, wenn sie fertig sind. Das ist ähnlich dem vorherigen Level (in dem ein Feature Branch auf den Server geschoben wird), nur mit einem zusätzlichen Schritt.", + "", + "Einige Entwickler pushen und pullen nur auf dem `master` -- dadurch ist `master` immer aktuell zu seinem Gegenstück auf dem Server (`o/master`).", + "", + "Für diesen Ablauf werden wir also zwei Dinge kombinieren:", + "", + "* einen Feature Bran in `master` reintegrieren und", + "* vom entfernten Server pushen und pullen." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Schauen wir uns zur Erinnerung schnell noch mal an wie man den `master` aktualisiert und seine Commits pusht." + ], + "afterMarkdowns": [ + "Wir haben hier zwei Befehle ausgeführt, die:", + "", + "* unsere Commits auf die neuen Commits vom Server gepackt und", + "* unsere Commits zum Server gepusht haben." + ], + "command": "git pull --rebase; git push", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Dieser Level ist ziemlich heftig -- hier ist im Groben der Weg:", + "", + "* Es gibt drei Feature Branches -- `side1`, `side2` und `side3`.", + "* Wir möchten jedes dieser Features, in dieser Reihenfolge, auf den Server bringen.", + "* Der Server hat Commits, die wir noch nicht haben, diese müssen also bei uns integriert werden.", + "", + ":O Krass! Viel Erfolg, diesen Level zu schaffen ist ein großer Schritt." + ] + } + } + ] } } }; From 059cb003a28b9a1ebffb2f69621ce6c92185a664 Mon Sep 17 00:00:00 2001 From: Jens Bremmekamp Date: Sun, 22 Dec 2013 00:06:00 +0100 Subject: [PATCH 13/47] Lots of minor translation errors fixed --- src/js/dialogs/sandbox.js | 13 +++----- src/levels/index.js | 2 +- src/levels/intro/branching.js | 4 +-- src/levels/rampup/relativeRefs.js | 6 ++-- src/levels/remote/clone.js | 10 +++--- src/levels/remote/fakeTeamwork.js | 2 +- src/levels/remote/fetch.js | 6 ++-- src/levels/remote/fetchArgs.js | 7 ++-- src/levels/remote/fetchRebase.js | 6 ++-- src/levels/remote/mergeManyFeatures.js | 45 ++++++++++++++++++++++++++ src/levels/remote/pull.js | 2 +- src/levels/remote/pullArgs.js | 4 +-- src/levels/remote/push.js | 2 +- src/levels/remote/pushArgs.js | 3 +- src/levels/remote/pushArgs2.js | 2 +- src/levels/remote/remoteBranches.js | 2 +- src/levels/remote/tracking.js | 4 +-- 17 files changed, 80 insertions(+), 40 deletions(-) diff --git a/src/js/dialogs/sandbox.js b/src/js/dialogs/sandbox.js index 09697a1b..2c560be7 100644 --- a/src/js/dialogs/sandbox.js +++ b/src/js/dialogs/sandbox.js @@ -61,10 +61,7 @@ exports.dialog = { markdowns: [ '## Willkommen bei LearnGitBranching!', '', - 'Diese Anwendung wurde geschrieben um die umfangreichen', - 'Zusammenhänge beim Arbeiten mit Branches in Git zu', - 'verdeutlichen. Wir hoffen du hast Spaß und lernst', - 'vielleicht sogar etwas dabei!', + 'Der Sinn dieser Anwendung ist, die umfangreichen und komplexen Zusammenhänge der Prozesse, die bei der Arbeit mit Git ablaufen, zu verdeutlichen. Ich hoffe du hast Spaß dabei und lernst vielleicht sogar etwas!', '', '# Demo!', '', @@ -72,7 +69,7 @@ exports.dialog = { '', '[http://pcottle.github.io/learnGitBranching/?demo](http://pcottle.github.io/learnGitBranching/?demo)', '', - 'Genervt von diesem Fenster? Häng `?NODEMO` an die URL um es los zu werden, siehe unten:', + 'Genervt von diesem Fenster? Häng `?NODEMO` an die URL um es los zu werden, so wie hier:', '', '[http://pcottle.github.io/learnGitBranching/?NODEMO](?NODEMO)' ] @@ -101,11 +98,11 @@ exports.dialog = { markdowns: [ '## Teilen macht Spaß!', '', - 'Teile diese Git-Bäume mit deinen Freunden mittels `export tree` und `import tree`', + 'Teile diese Git-Bäume mit deinen Freunden mittels `export tree` und `import tree`.', '', - 'Hast du Wissenswertes zu Git zu vermitteln? Versuch einen Level mit `build level` zu bauen oder probier den Level eines Freundes mit `import level` aus', + 'Hast du Wissenswertes zu Git zu vermitteln? Versuch einen Level mit `build level` zu bauen oder probier den Level eines Freundes mit `import level` aus.', '', - 'Um alle Kommandos zu sehen, gib `show commands` ein. Darunter gibt\'s kleine Schätze wie `undo` und `reset`', + 'Um alle Kommandos zu sehen, gib `show commands` ein. Darunter gibt\'s kleine Schätze wie `undo` und `reset`.', '', 'Für\'s Erste lass uns mit `levels` anfangen ...' ] diff --git a/src/levels/index.js b/src/levels/index.js index 507aa027..92b6ad2b 100644 --- a/src/levels/index.js +++ b/src/levels/index.js @@ -90,7 +90,7 @@ var sequenceInfo = exports.sequenceInfo = { tab: 'remote', displayName: { 'en_US': 'Push & Pull -- Git Remotes!', - 'de_DE': 'Push & Pull -- entfernte Repositories' + 'de_DE': 'Push & Pull -- entfernte Repositorys' }, about: { 'en_US': 'Time to share your 1\'s and 0\'s kids; coding just got social', diff --git a/src/levels/intro/branching.js b/src/levels/intro/branching.js index ba8693d7..4ddfd58f 100644 --- a/src/levels/intro/branching.js +++ b/src/levels/intro/branching.js @@ -11,7 +11,7 @@ exports.level = { }, "hint": { "en_US": "Make a new branch with \"git branch [name]\" and check it out with \"git checkout [name]\"", - "de_DE": 'Lege mit "git branch [Name]" einen neuen Branch an und checke ihn mit "git checkout [Name] aus', + "de_DE": 'Lege mit "git branch " einen neuen Branch an und checke ihn mit "git checkout aus', "ja": "ブランチの作成(\"git branch [ブランチ名]\")と、チェックアウト(\"git checkout [ブランチ名]\")", "fr_FR": "Faites une nouvelle branche avec \"git branch [nom]\" positionnez-vous dans celle-ci avec \"git checkout [nom]\"", "zh_CN": "用 'git branch [分支名]' 来创建分支,用 'git checkout [分支名]' 切换到分支", @@ -150,7 +150,7 @@ exports.level = { "Sagen wir Git also erst mal auf welchem Branch wir arbeiten wollen, und zwar mit", "", "```", - "git checkout [Name]", + "git checkout ", "```", "", "Das wird uns auf den neuen Branch bringen bevor wir unsere Änderungen committen." diff --git a/src/levels/rampup/relativeRefs.js b/src/levels/rampup/relativeRefs.js index 0aac617c..7d16b456 100644 --- a/src/levels/rampup/relativeRefs.js +++ b/src/levels/rampup/relativeRefs.js @@ -94,9 +94,9 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "## Rleative Referenzen", + "## Relative Referenzen", "", - "Es kann etwas mühselig werden, sich in einem Commit-Baum mittels Angabe der Hashes zu bewegen. Im echten Leven hat man normalerweise keine hübsche Visualisierung des Baumes neben seinem Terminal, also benutzt man `git log` um die Hashes zu sehen.", + "Es kann etwas mühselig werden, sich in einem Commit-Baum mittels Angabe der Hashes zu bewegen. Im echten Leben hat man normalerweise keine hübsche Visualisierung des Baumes neben seinem Terminal, also benutzt man `git log` um die Hashes zu sehen.", "", "Außerdem sind die echten Hashes sehr viel länger und nicht fortlaufend nummeriert. Beispielsweise heißt der Hash, mit dem ich den letzten Level committet habe, in echt `fed2da64c0efc5293610bdd892f82a58e8cbc5d8`. Nicht gerade einprägsam ...", "", @@ -142,7 +142,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Du kannst auch `HEAD` als Basis für relative Referenzen benutzen. Lass uns das ein paar verwenden, um uns im Commit-Baum nach oben zu bewegen." + "Du kannst auch `HEAD` als Basis für relative Referenzen benutzen. Lass uns das ein paar Mal verwenden, um uns im Commit-Baum nach oben zu bewegen." ], "afterMarkdowns": [ "Das war einfach. Wir reisen mit `HEAD^` in der Zeit zurück." diff --git a/src/levels/remote/clone.js b/src/levels/remote/clone.js index 62d01f7d..a7ce7bc0 100644 --- a/src/levels/remote/clone.js +++ b/src/levels/remote/clone.js @@ -75,15 +75,15 @@ exports.level = { "markdowns": [ "## Git Remotes", "", - "Entfernte Repositorys sind nicht weiter kompliziert. In dieser Welt des Cloud Computings könnte man vielleicht glauben, dass hiter entfernten Git-Repositorys eine Menge Magie steckt, aber es sind einfach nur Kopien eines Repositorys auf einem anderen Rechner. Du kannst mit diesem Rechner typischerweise über das Internet kommunizieren, was es dir ermöglicht Commits hin und her zu schicken.", + "Entfernte Repositorys sind nicht weiter kompliziert. In dieser Welt des Cloud Computings könnte man vielleicht glauben, dass hinter entfernten Git-Repositorys eine Menge Magie steckt, aber es sind einfach nur Kopien eines Repositorys auf einem anderen Rechner. Du kannst mit diesem Rechner typischerweise über das Internet kommunizieren, was es dir ermöglicht Commits hin und her zu schicken.", "", - "Nichtsdestoweniger haben entfernte Repositorys eine Menge toller Eigenschaften:", + "Nichts desto weniger haben entfernte Repositorys eine Menge toller Eigenschaften:", "", - "- Vor allem: sie sind ein Super-Backup! Lokale Git-Repositorys können deine Arbeitskopie ein jeden beliebigen früheren Zustand versetzen (wie du ja weißt), aber all diese Informationen liegen eben bei dir lokal. Wenn es Kopien von deinem Repository auf anderen Rechnern gibt, kannst du ruhig all deine Daten verlieren und trotzdem genau da weitermachen, wo du aufgehört hast.", + "- Vor allem: sie sind ein super Backup! Lokale Git-Repositorys können deine Arbeitskopie ein jeden beliebigen früheren Zustand versetzen (wie du ja weißt), aber all diese Informationen liegen eben bei dir lokal. Wenn es Kopien von deinem Repository auf anderen Rechnern gibt, kannst du ruhig all deine Daten verlieren und trotzdem genau da weitermachen, wo du aufgehört hast.", "", - "- Noch wichtiger: Remotes geben dem Entwicklen eine soziale Komponente! Wenn eine Kopie deines Projekts woanders liegt können deine Freunde sehr einfach etwas zu dem Projekt beitragen (oder sich deine neuesten Änderungen holen).", + "- Noch wichtiger: Remotes geben dem Entwickeln eine soziale Komponente! Wenn eine Kopie deines Projekts woanders liegt können deine Freunde sehr einfach etwas zu dem Projekt beitragen (oder sich deine neuesten Änderungen holen).", "", - "Websites, die die Aktivitäten um diese entfernten Repositorys darstellen (wie [Github](https://github.com/) oder [Phabricator](http://phabricator.org/)) erfreuen sich zunehmender Beliebtheit, aber entfernte Repositorys sind _immer_ das Rückgrat fü diese Werkzeuge. Deshalb ist es wichtig, sie zu verstehen." + "Websites, die die Aktivitäten um diese entfernten Repositorys darstellen (wie [Github](https://github.com/) oder [Phabricator](http://phabricator.org/)) erfreuen sich zunehmender Beliebtheit, aber entfernte Repositorys sind _immer_ das Rückgrat für diese Werkzeuge. Deshalb ist es wichtig, sie zu verstehen." ] } }, diff --git a/src/levels/remote/fakeTeamwork.js b/src/levels/remote/fakeTeamwork.js index 72015d16..7cab2b04 100644 --- a/src/levels/remote/fakeTeamwork.js +++ b/src/levels/remote/fakeTeamwork.js @@ -113,7 +113,7 @@ exports.level = { "markdowns": [ "Die kommenden Level werden recht anspruchsvoll, daher verlangen wir auch in diesem Level schon etwas mehr.", "", - "Leg log und erstelle ein Remote (mit `git clone`), simuliere ein paar Änderungen auf dem Server, committe lokal und dann zieh dir die Änderungen vom Server. Das ist wie mehrere Level in einem!" + "Leg los und erstelle ein Remote (mit `git clone`), simuliere ein paar Änderungen auf dem Server, committe lokal und dann zieh dir die Änderungen vom Server. Das ist wie mehrere Level in einem!" ] } } diff --git a/src/levels/remote/fetch.js b/src/levels/remote/fetch.js index c985a17c..acbcc932 100644 --- a/src/levels/remote/fetch.js +++ b/src/levels/remote/fetch.js @@ -96,7 +96,7 @@ exports.level = { "", "In diesem Level werden wir lernen, wie man Daten _von_ einem entfernten Repository holt -- der entsprechende Befehl heißt praktischerweise `git fetch`.", "", - "Dir wird auffallen, dass sich mit der Aktualisierung unserer Darstellung des entfernten Repositorys die _Remote_ Branches auf den neuesten Stand gebracht werden. Das passt zum vorherigen Level über Remote Branches." + "Dir wird auffallen, dass mit der Aktualisierung unserer Darstellung des entfernten Repositorys die _Remote_ Branches auf den neuesten Stand gebracht werden. Das passt zum vorherigen Level über Remote Branches." ] } }, @@ -128,7 +128,7 @@ exports.level = { "", "Wie du dich vielleicht erinnerst, haben wir im letzten Level gesagt, dass die Remote Branches den Zustand der Branches auf dem entfernten Repository darstellen _seit_ du das letzte Mal dieses Repository angesprochen hast. `git fetch` ist die Methode mit der du das Repository ansprichst! Der Zusammenhang zwischen Remote Branches und `git fetch` ist damit hoffentlich klar.", "", - "`git fetch` kommuniziert mir dem entfernten Repository in der Regel über das Internet (über ein Protokoll wie `http://` oder `git://`).", + "`git fetch` kommuniziert mit dem entfernten Repository in der Regel über das Internet (über ein Protokoll wie `http://` oder `git://`).", "" ] } @@ -141,7 +141,7 @@ exports.level = { "", "`git fetch` ändert allerdings überhaupt nichts an _deinen_ lokalen Branches. Es aktualisiert nicht deinen `master` oder ändert irgendetwas an deinem Checkout.", "", - "Das ist wichtig zu wissen, denn eine Menge Entwickler glauben, wenn sie `git fetch` ausführen würden ihre lokalen Branches auf den Stand des entfernten Repositorys gebracht. Es lädt zwar alle Daten herunter, damit man diese Aktualisierung durchführen kann, aber es ändert _nichts_ an deinen lokalen branches. Wir werden in späteren Level Befehle genau dafür kennenlernen. :D", + "Das ist wichtig zu wissen, denn eine Menge Entwickler glauben, wenn sie `git fetch` ausführen würden ihre lokalen Branches auf den Stand des entfernten Repositorys gebracht. Es lädt zwar alle Daten herunter, damit man diese Aktualisierung durchführen kann, aber es ändert _nichts_ an deinen lokalen Branches. Wir werden in späteren Level Befehle genau dafür kennenlernen. :D", "", "Am Ende des Tages kannst du dir `git fetch` also als den Donwload-Schritt vorstellen." ] diff --git a/src/levels/remote/fetchArgs.js b/src/levels/remote/fetchArgs.js index d6bb7850..3500f9ca 100644 --- a/src/levels/remote/fetchArgs.js +++ b/src/levels/remote/fetchArgs.js @@ -8,7 +8,7 @@ exports.level = { }, "hint": { "en_US": "Pay attention how the commit ids may have swapped! You can read slides again with \"help level\"", - "de_DE": "Beachtw wie die Commit IDs getauscht wurden! Du kannst den Einführungsdialog mit \"help level\" erneut anzeigen" + "de_DE": "Beachte wie die Commit IDs getauscht wurden! Du kannst den Einführungsdialog mit \"help level\" erneut anzeigen" }, "startDialog": { "en_US": { @@ -173,8 +173,7 @@ exports.level = { "Durch Angabe eines Ortes ..." ], "afterMarkdowns": [ - "... laden wir die fehlenden Commits von `foo` und packen sie auf `o/foo` drauf", - "We download only the commits from `foo` and place them on `o/foo`" + "... laden wir die fehlenden Commits von `foo` und packen sie auf `o/foo` drauf." ], "command": "git fetch origin foo", "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" @@ -186,7 +185,7 @@ exports.level = { "markdowns": [ "Du wunderst dich vielleicht warum Git diese Commits auf den `o/foo` Branch gepacht hat, anstatt einfach direkt auf den lokalen Branch `foo`? Zeigt der Parameter `` nicht einen Ort an, der sowohl lokal als auch entfernt existiert?", "", - "Nun ja, Git geht diesen Schritt weil du auf `foo` ja noch Commits haben könntest, die nicht auf dem Server sind, und da will es nichts durcheinander bringen. Ähnlich wie beim früheren Level zu `git fetch` -- es aktualisiert nicht deine Lokalen Arbeits-Branches, es lädt die Commits nur in die `o` (bzw. `origin`) Branches, damit du sie dir in Ruhe anschauen und integrieren kannst.", + "Nun ja, Git geht diesen Schritt weil du auf `foo` ja noch Commits haben könntest, die nicht auf dem Server sind, und da will es nichts durcheinander bringen. Ähnlich wie beim früheren Level zu `git fetch` -- es aktualisiert nicht deine lokalen Arbeits-Branches, es lädt die Commits nur in die `o` (bzw. `origin`) Branches, damit du sie dir in Ruhe anschauen und integrieren kannst.", "" ] } diff --git a/src/levels/remote/fetchRebase.js b/src/levels/remote/fetchRebase.js index a3282063..e4467291 100644 --- a/src/levels/remote/fetchRebase.js +++ b/src/levels/remote/fetchRebase.js @@ -164,7 +164,7 @@ exports.level = { "", "Bisher haben wir gesehen wie man per `pull` Commits von Anderen ins lokale Repository holt und die eigenen Änderungen in ein entferntes `push`t. Ist doch ziemlich einfach, wie kann man da durcheinander kommen?", "", - "Die Schwierigkeiten entstehen, wenn die History der beiden Repositorys *divergieren*, also voneinander abweichen. Bevor wir die Einzelheiten besprechen, schauen wir uns ein Beispiel an ...", + "Die Schwierigkeiten entstehen, wenn die Historys der beiden Repositorys *divergieren*, also voneinander abweichen. Bevor wir die Einzelheiten besprechen, schauen wir uns ein Beispiel an ...", "" ] } @@ -173,7 +173,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "Stellt dir vor du holst dir Montags ein Repository per `clone` und fängst an, an einem Feature zu arbeiten. Bis Freitag soll es fertig und veröffentlicht sein -- doch, oh je! Deine Kollegen haben eine Menge Code während der Woche geschrieben, der dein Feature hat veralten lassen (und überflüssig gemacht hat). Sie haben diesen Code außerdem zum entfernten Repository gepusht, und dadurch basiert *deine* harte Arbeit jetzt auf einer *alten* Version des Projektes, die nicht länger relevant ist.", + "Stell dir vor du holst dir Montags ein Repository per `clone` und fängst an, an einem Feature zu arbeiten. Bis Freitag soll es fertig und veröffentlicht sein -- doch, oh je! Deine Kollegen haben eine Menge Code während der Woche geschrieben, der dein Feature hat veralten lassen (und überflüssig gemacht hat). Sie haben diesen Code außerdem zum entfernten Repository gepusht, und dadurch basiert *deine* harte Arbeit jetzt auf einer *alten* Version des Projektes, die nicht länger relevant ist.", "", "In diesem Fall ist ein `git push` problematisch. Wenn du es ausführst, soll Git das entfernte Repository in den Zustand von Montag zurückversetzen? Soll es versuchen deinen Code auf die aktuelle Version zu packen? Oder soll es deine Änderungen einfach ignorieren, weil sie total veraltet sind?", "", @@ -188,7 +188,7 @@ exports.level = { "Bla bla bla. Schauen wir uns das lieber in Aktion an:" ], "afterMarkdowns": [ - "Siehst du? Nichts passiert, weil der Befehl fehlschlägt. `git push` schlägt fehl, weil der neueste Commit `C3` auf dem Commit `C1` auf dem Remote basiert. Der entfernte Server hat mittlerweile jedoch `C2` gepusht bekommen, also lässt Git deinen Push jetzt nicht mehr zu." + "Siehst du? Nichts passiert, weil der Befehl fehlschlägt. `git push` schlägt fehl, weil der neueste Commit `C3` auf dem Commit `C1` des Remotes basiert. Der entfernte Server hat mittlerweile jedoch `C2` gepusht bekommen, also lässt Git deinen Push jetzt nicht mehr zu." ], "command": "git push", "beforeCommand": "git clone; git fakeTeamwork; git commit" diff --git a/src/levels/remote/mergeManyFeatures.js b/src/levels/remote/mergeManyFeatures.js index 8afeb1bd..96bb770e 100644 --- a/src/levels/remote/mergeManyFeatures.js +++ b/src/levels/remote/mergeManyFeatures.js @@ -13,6 +13,51 @@ exports.level = { "compareOnlyMaster": true, "startDialog": { "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Why not merge?", + "", + "In order to push new updates to the remote, all you need to do is *incorporate* the latest changes from the remote. That means you can either rebase *or* merge in the remote branch (e.g. `o/master`).", + "", + "So if you can do either method, why have the lessons focused on rebasing so far? Why is there no love for `merge` when working with remotes?", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Theres a lot of debate about the tradeoffs between merging and rebasing in the development community. Here are the general pros / cons of rebasing:", + "", + "Pros:", + "", + "* Rebasing makes your commit tree look very clean since everything is in a straight line", + "", + "Cons:", + "", + "* Rebasing modifies the (apparent) history of the commit tree.", + "", + "For example, commit `C1` can be rebased *past* `C3`. It then appears that the work for `C1'` came after `C3` when in reality it was completed beforehand.", + "", + "Some developers love to preserve history and thus prefer merging. Others (like myself) prefer having a clean commit tree and prefer rebasing. It all comes down to preferences :D" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "For this level, let's try to solve the previous level but with *merging* instead. It may get a bit hairy but it illustrates the point well" + ] + } + } + ] + }, + "de_DE": { "childViews": [ { "type": "ModalAlert", diff --git a/src/levels/remote/pull.js b/src/levels/remote/pull.js index 3adefabd..73b39f43 100644 --- a/src/levels/remote/pull.js +++ b/src/levels/remote/pull.js @@ -111,7 +111,7 @@ exports.level = { "Was passiert wohl, wenn wir stattdessen `git pull` benutzen?" ], "afterMarkdowns": [ - "Exakt dasselbe! Das sollte recht deutlich machen, dass `git pull` nur eine Abkürzung für `git fetch` gefolgt von einem Merge des gerade aktualisierten Branches ist." + "Dasselbe in Pink. Das sollte recht deutlich machen, dass `git pull` nur eine Abkürzung für `git fetch` gefolgt von einem Merge des gerade aktualisierten Branches ist." ], "command": "git pull", "beforeCommand": "git clone; git commit; git fakeTeamwork" diff --git a/src/levels/remote/pullArgs.js b/src/levels/remote/pullArgs.js index 7223f570..09a38fd9 100644 --- a/src/levels/remote/pullArgs.js +++ b/src/levels/remote/pullArgs.js @@ -111,7 +111,7 @@ exports.level = { "", "`git fetch origin foo; git merge o/foo`", "", - "Unde ...", + "Und ...", "", "`git pull origin bar~1:bugFix` ist dasselbe wie:", "", @@ -140,7 +140,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Funktionniert das auch wenn man Quelle und Ziel angibt? Aber sicher! Das sehen wir hier:" + "Funktioniert das auch wenn man Quelle und Ziel angibt? Aber sicher! Das sehen wir hier:" ], "afterMarkdowns": [ "Wow, das ist eine Menge in einem einzelnen Befehl. Wir haben lokal einen neuen Branch namens `foo` erstellt, die Commits vom `master` des Servers dorthin heruntergeladen und ihn danach in unseren aktuell ausgecheckten Commit `bar` gemerged." diff --git a/src/levels/remote/push.js b/src/levels/remote/push.js index 8e4d2a26..b019bd1a 100644 --- a/src/levels/remote/push.js +++ b/src/levels/remote/push.js @@ -66,7 +66,7 @@ exports.level = { "", "`git push` ist dafür verantwortlich _deine_ Änderungen zu einem bestimmten entfernten Server hochzuladen und dort zu integrieren. Sobald das `git push` durch ist, können alle deine Freunde diese Änderungen zu sich herunterladen.", "", - "Du kannst dir `git push` als einen Befehl zu \"Veröffentlichen\" deiner Arbeit vorstellen. Es gibt da noch ein paar Feinheiten, aber lass uns mal mit kleinen Schritten anfangen." + "Du kannst dir `git push` als einen Befehl zum \"Veröffentlichen\" deiner Arbeit vorstellen. Es gibt da noch ein paar Feinheiten, aber lass uns mal mit kleinen Schritten anfangen." ] } }, diff --git a/src/levels/remote/pushArgs.js b/src/levels/remote/pushArgs.js index 287e4b78..3c831ee5 100644 --- a/src/levels/remote/pushArgs.js +++ b/src/levels/remote/pushArgs.js @@ -92,12 +92,11 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "## Push arguments", "## Push-Optionen", "", "Großartig! Da du dich jetzt mit Remote Tracking Branches auskennst können wir anfangen, die Geheimnisse hinter `git push`, `fetch` und `pull` zu ergründen. Wir werden uns einen Befehl nach dem anderen vornehmen, aber die Funktionsweisen sind sich sehr ähnlich.", "", - "Zunächst schauen wir uns `git push` an. Du hast im Level über Remote Tracking schon mitbekommen, dass Git den Remot Server *und* den Branch herausbekommt, indem sich die Eigenschaften des aktuell ausgecheckten Branches ansieht (in denen das Remote steht, das der Branch \"trackt\"). Das ist das Verhalten bei keiner Angabe weiterer Optionen -- du kannst bei `git push` aber auch folgende setzen:", + "Zunächst schauen wir uns `git push` an. Du hast im Level über Remote Tracking schon mitbekommen, dass Git den Remote Server *und* den Branch herausbekommt, indem es sich die Eigenschaften des aktuell ausgecheckten Branches ansieht (in denen das Remote steht, das der Branch \"trackt\"). Das ist das Verhalten bei keiner Angabe weiterer Optionen -- du kannst bei `git push` aber auch folgende setzen:", "", "`git push `", "", diff --git a/src/levels/remote/pushArgs2.js b/src/levels/remote/pushArgs2.js index fea6c20c..141fb1d0 100644 --- a/src/levels/remote/pushArgs2.js +++ b/src/levels/remote/pushArgs2.js @@ -91,7 +91,7 @@ exports.level = { "", "Du erinnerst dich von dem vorherigen Level, dass, als wir `master` als \"Ort\" beim `git push` angegeben haben, daraus sowohl die *Quelle* als auch das *Ziel* für die Operation abgeleitet wurden.", "", - "Daher fragst du dich vielleicht -- was wenn wir möchten, dass Quelle und Ziel ander sind? Was wenn du Commits von einem lokalen Branch `foo` in den Branch `bar` auf einem Server schieben möchtest?", + "Daher fragst du dich vielleicht -- was wenn wir möchten, dass Quelle und Ziel anders sind? Was wenn du Commits von einem lokalen Branch `foo` in den Branch `bar` auf einem Server schieben möchtest?", "", "Tja, leider ist das in Git unmöglich .... ein Scherz! Natürlich ist das möglich. Git besitzt tonnenweise Flexibilität (eher zuviel, als zuwenig).", "", diff --git a/src/levels/remote/remoteBranches.js b/src/levels/remote/remoteBranches.js index 948fe462..e165ddfa 100644 --- a/src/levels/remote/remoteBranches.js +++ b/src/levels/remote/remoteBranches.js @@ -96,7 +96,7 @@ exports.level = { "markdowns": [ "### Was heißt `o/`?", "", - "Du fragst dich vielleicht was das `o/` am Anfang des Namens des Remote Branch bedeuten soll. Nun, Remote Branches folgen einer (zwingenden) Namenskonvention -- sie werden mit diesem Format gebildet:", + "Du fragst dich vielleicht was das `o/` am Anfang des Namens des Remote Branch bedeuten soll. Nun, Namen von Remote Branches folgen einer (zwingenden) Konvention -- sie werden mit diesem Format gebildet:", "", "* `/`", "", diff --git a/src/levels/remote/tracking.js b/src/levels/remote/tracking.js index d47e47fd..376dacd3 100644 --- a/src/levels/remote/tracking.js +++ b/src/levels/remote/tracking.js @@ -193,7 +193,7 @@ exports.level = { "Das gilt auch für `git push`." ], "afterMarkdowns": [ - "Bämm. Wir haben unsere Commits auf den `master` auf dem Server geschoben, obwohl unser lokale Branch völlig anders heißt." + "Bämm. Wir haben unsere Commits auf den `master` auf dem Server geschoben, obwohl unser lokaler Branch völlig anders heißt." ], "command": "git checkout -b foo o/master; git commit; git push", "beforeCommand": "git clone" @@ -220,7 +220,7 @@ exports.level = { "type": "GitDemonstrationView", "options": { "beforeMarkdowns": [ - "Schauen wir uns auch diese Meethode noch an ..." + "Schauen wir uns auch diese Methode noch an ..." ], "afterMarkdowns": [ "Genau wie vorher, nur ein bisschen ausführlicherer Befehl. Schick!" From c5a4106a439a80e142c80a45fc78e7995f08115a Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 22 Dec 2013 14:17:10 -0800 Subject: [PATCH 14/47] BIG Update -- Moving to Grunt >0.4 --- grunt.js => Gruntfile.js | 129 +++++++++++++++++++++------------------ package.json | 26 ++++---- 2 files changed, 85 insertions(+), 70 deletions(-) rename grunt.js => Gruntfile.js (75%) diff --git a/grunt.js b/Gruntfile.js similarity index 75% rename from grunt.js rename to Gruntfile.js index 378bd219..e7effe95 100644 --- a/grunt.js +++ b/Gruntfile.js @@ -79,40 +79,15 @@ module.exports = function(grunt) { }); grunt.initConfig({ - lint: { - files: ['grunt.js', 'src/**/*.js', 'spec/*.js'] - }, - compliment: { - compliments: [ - "Wow peter great work!", - "Such a professional dev environment", - "Can't stop the TRAIN", - "git raging" - ] - }, - hash: { - src: ['build/bundle.min.js', 'src/style/main.css'], - dest: 'build/' - }, - watch: { - files: '', - tasks: 'watching' - }, - min: { - dist: { - src: ['build/bundle.js'], - dest: 'build/bundle.min.js' - } - }, - rm: { - build: 'build/*' - }, - shell: { - gitAdd: { - command: 'git add build/' - } - }, + pkg: grunt.file.readJSON('package.json'), jshint: { + all: [ + 'Gruntfile.js', + 'spec/*.js', + 'src/js/**/*.js', + 'src/js/**/**/*.js', + 'src/levels/**/*.js', + ], options: { curly: true, // sometimes triple equality is just redundant and unnecessary @@ -142,21 +117,55 @@ module.exports = function(grunt) { boss: true, eqnull: true, browser: true, - debug: true + debug: true, + globals: { + Raphael: true, + require: true, + console: true, + describe: true, + expect: true, + it: true, + runs: true, + waitsFor: true, + exports: true, + module: true, + prompt: true, + process: true + } }, - globals: { - Raphael: true, - require: true, - console: true, - describe: true, - expect: true, - it: true, - runs: true, - waitsFor: true, - exports: true, - module: true, - prompt: true, - process: true + }, + compliment: { + compliments: [ + "Wow peter great work!", + "Such a professional dev environment", + "Can't stop the TRAIN", + "git raging" + ] + }, + hash: { + js: { + src: 'build/bundle.min.js', + dest: 'build/' + }, + css: { + src: 'src/style/main.css', + dest: 'build/' + } + }, + watch: { + files: '', + tasks: 'watching' + }, + uglify: { + build: { + src: ['build/bundle.js'], + dest: 'build/bundle.min.js' + } + }, + clean: ['build/*'], + shell: { + gitAdd: { + command: 'git add build/' } }, jasmine_node: { @@ -167,26 +176,30 @@ module.exports = function(grunt) { requirejs: false }, browserify: { - 'build/bundle.js': { - entries: ['src/**/*.js', 'src/js/**/*.js'] - //prepend: [''], + dist: { + files: { + 'build/bundle.js': ['src/**/*.js', 'src/js/**/*.js'], + }, } } }); // all my npm helpers - grunt.loadNpmTasks('grunt-jslint'); + grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-hash'); - grunt.loadNpmTasks('grunt-rm'); - grunt.loadNpmTasks('grunt-shell'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-shell-spawn'); grunt.loadNpmTasks('grunt-jasmine-node'); + grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.registerTask('build', 'rm browserify min hash buildIndex shell jasmine_node lint lintStrings compliment'); - grunt.registerTask('fastBuild', 'rm browserify hash buildIndex'); - grunt.registerTask('watching', 'fastBuild jasmine_node lint lintStrings'); + grunt.registerTask('build', + ['clean', 'browserify', 'uglify', 'hash', 'buildIndex', 'shell', 'jasmine_node', 'jshint', 'lintStrings', 'compliment'] + ); + grunt.registerTask('fastBuild', ['clean', 'browserify', 'hash', 'buildIndex']); + grunt.registerTask('watching', ['fastBuild', 'jasmine_node', 'jshint', 'lintStrings']); - grunt.registerTask('default', 'build'); - grunt.registerTask('test', 'jasmine_node'); + grunt.registerTask('default', ['build']); + grunt.registerTask('test', ['jasmine_node']); }; diff --git a/package.json b/package.json index 23d7934b..3bff18db 100644 --- a/package.json +++ b/package.json @@ -1,23 +1,25 @@ { "name": "LearnGitBranching", - "version": "0.5.0", + "version": "0.8.0", "devDependencies": { - "grunt": "~0.3.17", - "jasmine-node": "~1.11.0", - "grunt-browserify": "0.1.1", - "grunt-jslint": "~0.2.2-1", - "grunt-jasmine-node": "0.1.0", - "grunt-hash": "0.2.2", - "grunt-rm": "~0.0.3", - "grunt-shell": "0.1.4", - "prompt": "0.2.9" + "grunt": "~0.4.2", + "jasmine-node": "~1.12.0", + "grunt-browserify": "~1.3.0", + "grunt-jasmine-node": "~0.1.0", + "grunt-hash": "~0.5.0", + "prompt": "0.2.9", + "browserify": "~3.14.0", + "grunt-cli": "~0.1.11", + "grunt-contrib-uglify": "~0.2.7", + "grunt-contrib-jshint": "~0.7.2", + "grunt-contrib-clean": "~0.5.0", + "grunt-shell-spawn": "~0.3.0" }, "dependencies": { "backbone": "~0.9.9", "underscore": "~1.4.3", "jquery": "~1.7.3", "q": "~0.8.11", - "markdown": "~0.4.0", - "grunt-shell": "~0.1.4" + "markdown": "~0.4.0" } } From 8d503d6049f796ee1cbf630e49c0a83b208a749c Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 22 Dec 2013 14:23:21 -0800 Subject: [PATCH 15/47] Pull Request #152 Issue #152 credit for german translation --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bb02b2f4..50ecd6c2 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ LearnGitBranching is a git repository visualizer, sandbox, and series of educational tutorials and challenges. Its primary purpose is to help developers understand git through the power of visualization (something that's absent when working on the command line). You can input a variety of commands into LearnGitBranching (LGB) -- as commands are processed, the nearby commit tree will dynamically update to reflect the effects of each command: + + This visualization combined with tutorials and "levels" can help both beginners and intermediate developers polish their version control skills. A quick demo is available here: @@ -37,6 +39,8 @@ LearnGitBranching is a pretty simple application (from a technical perspective). Because the app contains a lot of code, I have written everything into Nodejs-style modules. The modules are packaged together with the `Browserify` and then sent down in a format the browser can understand. +As of December 2013, I've migrated the build process to use Grunt >0.4, since the older version was giving a lot of people build headaches. It should be fairly rock solid now! + Here is the high level process of the build: * Code is written into the node.js modules which require other modules @@ -55,8 +59,8 @@ Thus, if you build the app locally, all you have to do in order to run the app i ## Building yourself / Contributing Functionality For contributing core functionality in the app, you'll probably want to test your changes -at least once before submitting a pull request. That means you'll need the `grunt` build tool. It's a fairly -common tool, however I use a slightly older version. +at least once before submitting a pull request. That means you'll need the `grunt` build tool: +http://gruntjs.com/getting-started You'll also need `npm` to download all the dependencies of the project. @@ -68,11 +72,10 @@ cd learnGitBranching npm install # to install all the node modules I depend on git checkout -b newAwesomeFeature # some changes -./node_modules/grunt/bin/grunt fastBuild # to use the npm version of grunt +grunt fastBuild # after building you can open up your browser to the index.html that is generated and see your changes -grunt watch # will keep watch over files and fastBuild whenever they change. lot of CPU though # more changes -./node_modules/grunt/bin/grunt build # build runs the tests and lint as well +grunt build git commit -am "My new sweet feature!" git push # go online and request a pull @@ -92,6 +95,7 @@ And the following heroes for assisting in translating: * "scientific-coder" * "ace-coder" * Joël Thieffry +* Jens Bremmekamp ("nem75") Also huge shoutout for everyone who has put up a pull request that was pulled: @@ -114,7 +118,7 @@ Also huge shoutout for everyone who has put up a pull request that was pulled: * Allen Guo * Timothy Qiu * Hyunjin CHA -* "nem75" +* Jens Bremmekamp ("nem75") * Fabio Crisci (piuccio) * Max Sikström (pengi) [tag support!!] * "rogererens" From 2c982b704bc72ec9bf3de792df60067f4f71784c Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 22 Dec 2013 14:36:36 -0800 Subject: [PATCH 16/47] readme update --- README.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 50ecd6c2..9a89ae61 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,8 @@ Thus, if you build the app locally, all you have to do in order to run the app i ## Building yourself / Contributing Functionality For contributing core functionality in the app, you'll probably want to test your changes -at least once before submitting a pull request. That means you'll need the `grunt` build tool: +at least once before submitting a pull request. That means you'll need the "Grunt.js" build tool to build the app: + http://gruntjs.com/getting-started You'll also need `npm` to download all the dependencies of the project. @@ -70,12 +71,17 @@ The general workflow / steps are below: git clone cd learnGitBranching npm install # to install all the node modules I depend on + git checkout -b newAwesomeFeature -# some changes -grunt fastBuild -# after building you can open up your browser to the index.html that is generated and see your changes -# more changes -grunt build +vim ./src/js/git/index.js # some changes +grunt fastBuild # skips tests and linting, faster build + +# after building you can open up your browser to the index.html +# file generated and see your changes + +vim ./src/js/git/index.js # more changes +grunt build # runs tests and lint + git commit -am "My new sweet feature!" git push # go online and request a pull From 316dd916bd4af92abc4deac66ece22d78df5e7fd Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 22 Dec 2013 22:23:24 -0800 Subject: [PATCH 17/47] Error in git clone behavior Pull Request #152 --- src/levels/remote/tracking.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/levels/remote/tracking.js b/src/levels/remote/tracking.js index 376dacd3..425dd351 100644 --- a/src/levels/remote/tracking.js +++ b/src/levels/remote/tracking.js @@ -37,11 +37,13 @@ exports.level = { "", "You may be wondering how this property got set on the `master` branch when you didn't run any commands to specify it. Well, when you clone a repository with git, this property is actually set for you automatically. ", "", - "During a clone, git creates a remote branch for every branch on the remote (aka branches like `o/master`) and then, for each remote branch, creates a local branch to *track* that remote branch (aka `master`). Thats why you may have seen the following command output:", + "During a clone, git creates a remote branch for every branch on the remote (aka branches like `o/master`). It then creates a local branch that tracks the currently active branch on the remote, which is `master` in most cases.", "", - " local branch \"master\" set to track remote branch \"o/master\"", + "Once git clone is complete, you only have one local branch (so you aren't overwhelmed) but you can see all the different branches on the remote (if you happen to be very curious). It's the best of both worlds!", "", - "When running `git clone`." + "This also explains why you may see the following command output when cloning:", + "", + " local branch \"master\" set to track remote branch \"o/master\"" ] } }, From c3c3a50bdd5361951f45f552ef0611f17c03c2a8 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Sun, 22 Dec 2013 22:24:27 -0800 Subject: [PATCH 18/47] gruntfile update --- Gruntfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Gruntfile.js b/Gruntfile.js index e7effe95..2f43b5eb 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -196,6 +196,7 @@ module.exports = function(grunt) { grunt.registerTask('build', ['clean', 'browserify', 'uglify', 'hash', 'buildIndex', 'shell', 'jasmine_node', 'jshint', 'lintStrings', 'compliment'] ); + grunt.registerTask('lint', ['jshint', 'compliment']); grunt.registerTask('fastBuild', ['clean', 'browserify', 'hash', 'buildIndex']); grunt.registerTask('watching', ['fastBuild', 'jasmine_node', 'jshint', 'lintStrings']); From e7d9b76b9851b2dccca9a7df654820151aee1234 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 23 Dec 2013 10:15:16 -0800 Subject: [PATCH 19/47] moved another function to graph --- src/js/git/commands.js | 3 ++- src/js/git/index.js | 52 +++++++++--------------------------------- src/js/graph/index.js | 31 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 975bfbd3..7823bf3c 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -1,6 +1,7 @@ var _ = require('underscore'); var intl = require('../intl'); +var Graph = require('../graph'); var Errors = require('../util/errors'); var CommandProcessError = Errors.CommandProcessError; var GitError = Errors.GitError; @@ -177,7 +178,7 @@ var commandConfig = { command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE); - var set = engine.getUpstreamSet('HEAD'); + var set = Graph.getUpstreamSet(engine, 'HEAD'); // first resolve all the refs (as an error check) var toCherrypick = _.map(generalArgs, function(arg) { var commit = engine.getCommitFromRef(arg); diff --git a/src/js/git/index.js b/src/js/git/index.js index c7bf862f..d2be67d4 100644 --- a/src/js/git/index.js +++ b/src/js/git/index.js @@ -27,12 +27,6 @@ function catchShortCircuit(err) { } } -function invariant(truthy, reason) { - if (!truthy) { - throw new Error(reason); - } -} - function GitEngine(options) { this.rootCommit = null; this.refs = {}; @@ -174,7 +168,7 @@ GitEngine.prototype.exportTreeForBranch = function(branchName) { // is not connected to branchname var tree = this.exportTree(); // get the upstream set - var set = this.getUpstreamSet(branchName); + var set = Graph.getUpstreamSet(this, branchName); // now loop through and delete commits var commitsToLoop = tree.commits; tree.commits = {}; @@ -934,7 +928,7 @@ GitEngine.prototype.checkUpstreamOfSource = function( // target. Hence target should be strictly upstream of source // lets first get the upstream set from source's dest branch - var upstream = source.getUpstreamSet(sourceBranch); + var upstream = Graph.getUpstreamSet(source, sourceBranch); var targetLocationID = target.getCommitFromRef(targetBranch).get('id'); if (!upstream[targetLocationID]) { @@ -954,7 +948,7 @@ GitEngine.prototype.getTargetGraphDifference = function( options = options || {}; sourceBranch = source.resolveID(sourceBranch); - var targetSet = target.getUpstreamSet(targetBranch); + var targetSet = Graph.getUpstreamSet(target, targetBranch); var sourceStartCommit = source.getCommitFromRef(sourceBranch); var sourceTree = source.exportTree(); @@ -1707,7 +1701,7 @@ GitEngine.prototype.pruneTreeAndPlay = function() { GitEngine.prototype.pruneTree = function() { var set = this.getUpstreamBranchSet(); // dont prune commits that HEAD depends on - var headSet = this.getUpstreamSet('HEAD'); + var headSet = Graph.getUpstreamSet(this, 'HEAD'); _.each(headSet, function(val, commitID) { set[commitID] = true; }); @@ -1802,7 +1796,7 @@ GitEngine.prototype.getUpstreamCollectionSet = function(collection) { }; GitEngine.prototype.getUpstreamHeadSet = function() { - var set = this.getUpstreamSet('HEAD'); + var set = Graph.getUpstreamSet(this, 'HEAD'); var including = this.getCommitFromRef('HEAD').get('id'); set[including] = true; @@ -1950,7 +1944,7 @@ GitEngine.prototype.hgRebase = function(destination, base) { // we need everything BELOW ourselves... var downstream = this.getDownstreamSet(base); // and we need to go upwards to the stop set - var stopSet = this.getUpstreamSet(destination); + var stopSet = Graph.getUpstreamSet(this, destination); var upstream = this.getUpstreamDiffSetFromSet(stopSet, base); // and NOWWWwwww get all the descendants of this set @@ -2032,7 +2026,7 @@ GitEngine.prototype.rebase = function(targetSource, currentLocation, options) { // then we BFS from currentLocation, using the downstream set as our stopping point. // we need to BFS because we need to include all commits below // pop these commits on top of targetSource and modify their ids with quotes - var stopSet = this.getUpstreamSet(targetSource); + var stopSet = Graph.getUpstreamSet(this, targetSource); var toRebaseRough = this.getUpstreamDiffFromSet(stopSet, currentLocation); return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options); }; @@ -2064,7 +2058,7 @@ GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, } // now get the stop set - var stopSet = this.getUpstreamSet(targetSource); + var stopSet = Graph.getUpstreamSet(this, targetSource); var toRebaseRough = []; // standard BFS @@ -2567,7 +2561,7 @@ GitEngine.prototype.status = function() { GitEngine.prototype.logWithout = function(ref, omitBranch) { // slice off the ^branch omitBranch = omitBranch.slice(1); - this.log(ref, this.getUpstreamSet(omitBranch)); + this.log(ref, Graph.getUpstreamSet(this, omitBranch)); }; GitEngine.prototype.log = function(ref, omitSet) { @@ -2612,7 +2606,7 @@ GitEngine.prototype.getCommonAncestor = function(ancestor, cousin) { throw new Error('Dont use common ancestor if we are upstream!'); } - var upstreamSet = this.getUpstreamSet(ancestor); + var upstreamSet = Graph.getUpstreamSet(this, ancestor); // now BFS off of cousin until you find something var queue = [this.getCommitFromRef(cousin)]; @@ -2631,7 +2625,7 @@ GitEngine.prototype.isUpstreamOf = function(child, ancestor) { // basically just do a completely BFS search on ancestor to the root, then // check for membership of child in that set of explored nodes - var upstream = this.getUpstreamSet(ancestor); + var upstream = Graph.getUpstreamSet(this, ancestor); return upstream[child.get('id')] !== undefined; }; @@ -2658,29 +2652,6 @@ GitEngine.prototype.getDownstreamSet = function(ancestor) { return exploredSet; }; -GitEngine.prototype.getUpstreamSet = function(ancestor) { - var commit = this.getCommitFromRef(ancestor); - var ancestorID = commit.get('id'); - var queue = [commit]; - - var exploredSet = {}; - exploredSet[ancestorID] = true; - - var addToExplored = function(rent) { - exploredSet[rent.get('id')] = true; - queue.push(rent); - }; - - while (queue.length) { - var here = queue.pop(); - var rents = here.get('parents'); - - _.each(rents, addToExplored); - } - return exploredSet; -}; - - var Ref = Backbone.Model.extend({ initialize: function() { if (!this.get('target')) { @@ -2741,7 +2712,6 @@ var Branch = Ref.extend({ * * With that in mind, we change our branch model to support the following */ - setRemoteTrackingBranchID: function(id) { this.set('remoteTrackingBranchID', id); }, diff --git a/src/js/graph/index.js b/src/js/graph/index.js index 92f921ad..88774f2a 100644 --- a/src/js/graph/index.js +++ b/src/js/graph/index.js @@ -6,7 +6,14 @@ var Branch = Git.Branch; var Tag = Git.Tag; var Ref = Git.Ref; +function invariant(truthy, reason) { + if (!truthy) { + throw new Error(reason); + } +} + var Graph = { + getOrMakeRecursive: function( tree, createdSoFar, @@ -118,6 +125,30 @@ var Graph = { return result; }, + getUpstreamSet: function(engine, ancestor) { + invariant(typeof ancestor === 'string', 'pass in string'); + + var commit = engine.getCommitFromRef(ancestor); + var ancestorID = commit.get('id'); + var queue = [commit]; + + var exploredSet = {}; + exploredSet[ancestorID] = true; + + var addToExplored = function(rent) { + exploredSet[rent.get('id')] = true; + queue.push(rent); + }; + + while (queue.length) { + var here = queue.pop(); + var rents = here.get('parents'); + + _.each(rents, addToExplored); + } + return exploredSet; + }, + getUniqueObjects: function(objects) { var unique = {}; var result = []; From af12fe19f0acb7c956da62886d6c295b90dacb98 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Fri, 27 Dec 2013 10:14:29 -0800 Subject: [PATCH 20/47] helper bar now clickable pretty sure --- src/js/graph/index.js | 7 +------ src/js/intl/checkStrings.js | 13 ++++++++----- src/style/main.css | 2 +- src/template.index.html | 2 -- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/js/graph/index.js b/src/js/graph/index.js index 88774f2a..5d11d185 100644 --- a/src/js/graph/index.js +++ b/src/js/graph/index.js @@ -1,11 +1,5 @@ var _ = require('underscore'); -var Git = require('../git'); -var Commit = Git.Commit; -var Branch = Git.Branch; -var Tag = Git.Tag; -var Ref = Git.Ref; - function invariant(truthy, reason) { if (!truthy) { throw new Error(reason); @@ -88,6 +82,7 @@ var Graph = { parentObjs.push(this.getOrMakeRecursive(tree, createdSoFar, parentID)); }, this); + var Commit = require('../git').Commit; var commit = new Commit(_.extend( commitJSON, { diff --git a/src/js/intl/checkStrings.js b/src/js/intl/checkStrings.js index aa1ad087..4ecf3c66 100644 --- a/src/js/intl/checkStrings.js +++ b/src/js/intl/checkStrings.js @@ -1,4 +1,5 @@ var sys = require('sys'); +var util = require('../util'); var _ = require('underscore'); var child_process = require('child_process'); var strings = require('../intl/strings').strings; @@ -39,9 +40,11 @@ var processLines = function(lines) { }); }; -child_process.exec( - searchCommand, - function(err, output) { - processLines(output.split('\n')); -}); +if (!util.isBrowser()) { + child_process.exec( + searchCommand, + function(err, output) { + processLines(output.split('\n')); + }); +} diff --git a/src/style/main.css b/src/style/main.css index 70d520e3..e9c76bf4 100644 --- a/src/style/main.css +++ b/src/style/main.css @@ -211,7 +211,6 @@ body.hgMode #mainVisSpace .modeText.hgMode { /* Some interface things */ div.canvasTerminalHolder { - width: 100%; height: 100%; position: fixed; top: 0; @@ -300,6 +299,7 @@ div.canvasTerminalHolder > div.terminal-window-holder div.inside { div.canvasTerminalHolder > div.terminal-window-holder { max-width: 500px; + min-width: 500px; } /* Toolbar */ diff --git a/src/template.index.html b/src/template.index.html index ad17e01e..4f1c4e09 100644 --- a/src/template.index.html +++ b/src/template.index.html @@ -184,8 +184,6 @@ -
-
From 046e619a4858d15a68768929ab5e60aa1ce55d83 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 10:46:58 -0700 Subject: [PATCH 41/47] PR #166 slightly better centering and padding --- src/style/main.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/style/main.css b/src/style/main.css index 3df67f63..e58209e3 100644 --- a/src/style/main.css +++ b/src/style/main.css @@ -361,8 +361,8 @@ div.toolbar div.levelNameWrapper { text-align: center; position: relative; top: 5px; - margin-right: 23%; - margin-left: 90px; + margin: 0 100px; + padding-bottom: 10px; } span.levelToolbarSpan { From 6bdbb09d5af75d6de6780028c5aaaa9d5a3d9818 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 11:18:15 -0700 Subject: [PATCH 42/47] PR #166 fix animating shadow thing --- src/js/views/index.js | 2 +- src/style/main.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/js/views/index.js b/src/js/views/index.js index cba5e06e..fba47a90 100644 --- a/src/js/views/index.js +++ b/src/js/views/index.js @@ -923,7 +923,7 @@ var CanvasTerminalHolder = BaseView.extend({ this.$terminal.animate({ height: size.height, opacity: 1 - }, this.getAnimationTime(), function () { + }, this.getAnimationTime(), function() { self.recalcLayout(); }); }, diff --git a/src/style/main.css b/src/style/main.css index e58209e3..49556ff5 100644 --- a/src/style/main.css +++ b/src/style/main.css @@ -257,7 +257,7 @@ body.hgMode .visBackgroundColor { div.canvasTerminalHolder > div.terminal-window-holder > div.wrapper { height: 100%; - box-shadow: 0 0 30px rgb(0,0,0); + box-shadow: 0 0 12px rgb(0,0,0); cursor: pointer; border-radius: 0 0 5px 5px; } @@ -294,6 +294,7 @@ div.canvasTerminalHolder > div.terminal-window-holder div.inside { div.canvasTerminalHolder > div.terminal-window-holder { max-width: 500px; min-width: 500px; + overflow: visible !important; } /* Toolbar */ From 232cb0385c8c372e74c41b79818ca9d34fcf9032 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 11:27:40 -0700 Subject: [PATCH 43/47] PR #166 Fix the origin vis not resizing as well --- src/js/visuals/visualization.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/visuals/visualization.js b/src/js/visuals/visualization.js index b385c992..fd72e96b 100644 --- a/src/js/visuals/visualization.js +++ b/src/js/visuals/visualization.js @@ -283,6 +283,7 @@ var Visualization = Backbone.View.extend({ this.paper.setSize(width, height); this.gitVisuals.canvasResize(width, height); + this.originToo('myResize', arguments); } }); From f5887908cd48b9b32fce66210534f58d4d4c55c7 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 11:33:47 -0700 Subject: [PATCH 44/47] PR #166 intl-aware labeling of level toggle button --- src/js/intl/strings.js | 10 ++++++++++ src/js/level/index.js | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/js/intl/strings.js b/src/js/intl/strings.js index 1c8ceac0..e5d7f04b 100644 --- a/src/js/intl/strings.js +++ b/src/js/intl/strings.js @@ -579,6 +579,16 @@ exports.strings = { 'fr_FR': 'Vous êtes dans l\'éditeur de niveaux, donc plusieurs formes d\'aide sont disponibles. Merci de sélectionner soit "help general" soit "help builder"' }, /////////////////////////////////////////////////////////////////////////// + 'show-goal-button': { + '__desc__': 'button label to show goal', + 'en_US': 'Show Goal' + }, + /////////////////////////////////////////////////////////////////////////// + 'hide-goal-button': { + '__desc__': 'button label to hide goal', + 'en_US': 'Hide Goal' + }, + /////////////////////////////////////////////////////////////////////////// 'goal-to-reach': { '__desc__': 'title of window that shoes the goal tree to reach', 'en_US': 'Goal To Reach', diff --git a/src/js/level/index.js b/src/js/level/index.js index 96ba35ee..8f5b6df2 100644 --- a/src/js/level/index.js +++ b/src/js/level/index.js @@ -215,7 +215,7 @@ var Level = Sandbox.extend({ this.goalVis.hide(); this.goalWindowPos = position; this.goalWindowSize = size; - this.levelToolbar.$goalButton.text('Show Goal'); + this.levelToolbar.$goalButton.text(intl.str('show-goal-button')); }, resizeGoal: function () { @@ -274,7 +274,7 @@ var Level = Sandbox.extend({ showGoal: function(command, defer) { this.showSideVis(command, defer, this.goalCanvasHolder, this.initGoalVisualization); - this.levelToolbar.$goalButton.text('Hide Goal'); + this.levelToolbar.$goalButton.text(intl.str('hide-goal-button')); }, showSideVis: function(command, defer, canvasHolder, initMethod) { @@ -291,7 +291,7 @@ var Level = Sandbox.extend({ hideGoal: function(command, defer) { this.hideSideVis(command, defer, this.goalCanvasHolder); - this.levelToolbar.$goalButton.text('Show Goal'); + this.levelToolbar.$goalButton.text(intl.str('show-goal-button')); }, hideSideVis: function(command, defer, canvasHolder, vis) { From 3ad888498fe3eb48ba554cc81b68aac984be688a Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 11:50:06 -0700 Subject: [PATCH 45/47] PR #166 show the squeezer when maximizing and hide it when minimziing --- src/js/level/index.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/js/level/index.js b/src/js/level/index.js index 8f5b6df2..4b10adf2 100644 --- a/src/js/level/index.js +++ b/src/js/level/index.js @@ -195,7 +195,7 @@ var Level = Sandbox.extend({ // repo visualization a bit to make room. This way, you could have the goal window hang out on // the right side of the screen and still see the repo visualization. this.goalVis.customEvents.on('drag', _.bind(function(event, ui) { - if (ui.position.left > 0.5*$(window).width()) { + if (ui.position.left > 0.5 * $(window).width()) { if (!$('#goalPlaceholder').is(':visible')) { $('#goalPlaceholder').show(); this.mainVis.myResize(); @@ -216,6 +216,10 @@ var Level = Sandbox.extend({ this.goalWindowPos = position; this.goalWindowSize = size; this.levelToolbar.$goalButton.text(intl.str('show-goal-button')); + if ($('#goalPlaceholder').is(':visible')) { + $('#goalPlaceholder').hide(); + this.mainVis.myResize(); + } }, resizeGoal: function () { @@ -275,6 +279,11 @@ var Level = Sandbox.extend({ showGoal: function(command, defer) { this.showSideVis(command, defer, this.goalCanvasHolder, this.initGoalVisualization); this.levelToolbar.$goalButton.text(intl.str('hide-goal-button')); + // show the squeezer again we are to the side + if ($(this.goalVis.el).offset().left > 0.5 * $(window).width()) { + $('#goalPlaceholder').show(); + this.mainVis.myResize(); + } }, showSideVis: function(command, defer, canvasHolder, initMethod) { From 80e1d36cd0d2a0b4005153ceb229fd9f21213335 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 11:52:13 -0700 Subject: [PATCH 46/47] README for PR #166 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6e25550f..eb55ac2b 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ And the following heroes for assisting in translating: Also huge shoutout for everyone who has put up a pull request that was pulled: +* Sergey Krilov -- Draggable windows! * Aaron Schrab - 5x!! * Stephen Cavaliere * Andrew Ardill From db50adac0543eeaed187ef2182c5ec03ac85c0b9 Mon Sep 17 00:00:00 2001 From: Peter Cottle Date: Mon, 17 Mar 2014 12:02:37 -0700 Subject: [PATCH 47/47] after clicking a tab, remember which tab was clicked --- src/js/views/levelDropdownView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/views/levelDropdownView.js b/src/js/views/levelDropdownView.js index 5cbf79a0..cabe084f 100644 --- a/src/js/views/levelDropdownView.js +++ b/src/js/views/levelDropdownView.js @@ -89,6 +89,7 @@ var LevelDropdownView = ContainedBase.extend({ if (id === this.JSON.selectedTab) { return; } + this.selectedTab = id; this.updateTabTo(id); },