Patchwork D2938: grep: make grep search on working directory by default

login
register
mail settings
Submitter phabricator
Date March 25, 2018, 7:17 a.m.
Message ID <fc0843368d48bc7bf864766c5b0f8a1b@localhost.localdomain>
Download mbox | patch
Permalink /patch/29845/
State Not Applicable
Headers show

Comments

phabricator - March 25, 2018, 7:17 a.m.
sangeet259 updated this revision to Diff 7280.
sangeet259 marked 7 inline comments as done.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D2938?vs=7267&id=7280

REVISION DETAIL
  https://phab.mercurial-scm.org/D2938

AFFECTED FILES
  mercurial/commands.py
  tests/test-grep.t

CHANGE DETAILS




To: sangeet259, #hg-reviewers
Cc: av6, yuja, pulkit, mercurial-devel

Patch

diff --git a/tests/test-grep.t b/tests/test-grep.t
--- a/tests/test-grep.t
+++ b/tests/test-grep.t
@@ -24,74 +24,74 @@ 
 simple
 
   $ hg grep '.*'
-  port:4:export
-  port:4:vaportight
-  port:4:import/export
+  port:export
+  port:vaportight
+  port:import/export
   $ hg grep port port
-  port:4:export
-  port:4:vaportight
-  port:4:import/export
+  port:export
+  port:vaportight
+  port:import/export
 
 simple with color
 
   $ hg --config extensions.color= grep --config color.mode=ansi \
   >     --color=always port port
-  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc)
-  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc)
-  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc)
+  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc)
+  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc)
+  \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc)
 
 simple templated
 
   $ hg grep port \
   > -T '{file}:{rev}:{node|short}:{texts % "{if(matched, text|upper, text)}"}\n'
-  port:4:914fa752cdea:exPORT
-  port:4:914fa752cdea:vaPORTight
-  port:4:914fa752cdea:imPORT/exPORT
+  port::ffffffffffff:exPORT
+  port::ffffffffffff:vaPORTight
+  port::ffffffffffff:imPORT/exPORT
 
 simple JSON (no "change" field)
 
   $ hg grep -Tjson port
   [
    {
-    "date": [4.0, 0],
-    "file": "port",
-    "line_number": 1,
-    "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
-    "rev": 4,
+    "date": [0, 0],
+    "file": "port",
+    "line_number": 1,
+    "node": "ffffffffffffffffffffffffffffffffffffffff",
+    "rev": null,
     "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}],
-    "user": "spam"
-   },
-   {
-    "date": [4.0, 0],
+    "user": "test"
+   },
+   {
+    "date": [0, 0],
     "file": "port",
     "line_number": 2,
-    "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
-    "rev": 4,
+    "node": "ffffffffffffffffffffffffffffffffffffffff",
+    "rev": null,
     "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}],
-    "user": "spam"
-   },
-   {
-    "date": [4.0, 0],
+    "user": "test"
+   },
+   {
+    "date": [0, 0],
     "file": "port",
     "line_number": 3,
-    "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
-    "rev": 4,
+    "node": "ffffffffffffffffffffffffffffffffffffffff",
+    "rev": null,
     "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}],
-    "user": "spam"
+    "user": "test"
    }
   ]
 
 simple JSON without matching lines
 
   $ hg grep -Tjson -l port
   [
    {
-    "date": [4.0, 0],
-    "file": "port",
-    "line_number": 1,
-    "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
-    "rev": 4,
-    "user": "spam"
+    "date": [0, 0],
+    "file": "port",
+    "line_number": 1,
+    "node": "ffffffffffffffffffffffffffffffffffffffff",
+    "rev": null,
+    "user": "test"
    }
   ]
 
@@ -207,18 +207,17 @@ 
 other
 
   $ hg grep -l port port
-  port:4
+  port
   $ hg grep import port
-  port:4:import/export
+  port:import/export
 
   $ hg cp port port2
   $ hg commit -m 4 -u spam -d '5 0'
 
 follow
 
   $ hg grep --traceback -f 'import\n\Z' port2
-  port:0:import
-  
+  [1]
   $ echo deport >> port2
   $ hg commit -m 5 -u eggs -d '6 0'
   $ hg grep -f --all -nu port port2
@@ -256,26 +255,26 @@ 
   $ echo blue >> color
   $ hg ci -m 3
   $ hg grep orange
-  color:3:orange
+  color:orange
   $ hg grep --all orange
   color:3:+:orange
   color:2:-:orange
   color:1:+:orange
 
 test substring match: '^' should only match at the beginning
 
   $ hg grep '^.' --config extensions.color= --color debug
-  [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lack
-  [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|o]range
-  [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lue
+  [grep.filename|color][grep.sep|:][grep.match|b]lack
+  [grep.filename|color][grep.sep|:][grep.match|o]range
+  [grep.filename|color][grep.sep|:][grep.match|b]lue
 
 match in last "line" without newline
 
   $ $PYTHON -c 'fp = open("noeol", "wb"); fp.write(b"no infinite loop"); fp.close();'
   $ hg ci -Amnoeol
   adding noeol
   $ hg grep loop
-  noeol:4:no infinite loop
+  noeol:no infinite loop
 
   $ cd ..
 
@@ -292,8 +291,7 @@ 
   $ hg rename color colour
   $ hg ci -Am rename
   $ hg grep octarine
-  colour:1:octarine
-  color:0:octarine
+  colour:octarine
 
 Used to crash here
 
@@ -340,4 +338,29 @@ 
   $ hg grep "MaCam" --all
   binfile.bin:0:+: Binary file matches
 
-  $ cd ..
+Test that grep searches only on working directory
+  $ cd ..
+  $ hg init t5
+  $ cd t5
+  $ echo "mercurial revsets are awesome" > firstfile
+  $ hg add firstfile
+  $ hg commit -m  'adds firstfile'
+  $ hg rm firstfile
+  $ hg commit -m 'removes firstfile'
+  $ echo "mercurial revsets are awesome and makes life easier" > secondfile
+  $ echo "some generic text" > thirdfile
+  $ hg add secondfile thirdfile
+  $ hg commit -m 'adds two new files'
+  $ hg grep 'revsets'
+  secondfile:mercurial revsets are awesome and makes life easier
+  $ echo "another generic string" > fourthone
+
+Search on added but not commit i.e dirty working directory
+  $ hg add fourthone
+  $ hg grep "generic"
+  fourthone:another generic string
+  thirdfile:some generic text
+Search on untracked files | Should fail
+  $ echo "an apple a day" > genericname
+  $ hg grep "apple"
+  [1]
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2469,19 +2469,23 @@ 
         @util.cachefunc
         def binary():
             flog = getfile(fn)
-            return util.binary(flog.read(ctx.filenode(fn)))
+            try:
+                return util.binary(flog.read(ctx.filenode(fn)))
+            except AttributeError:
+                return ctx.filectx(fn).isbinary()
 
         fieldnamemap = {'filename': 'file', 'linenumber': 'line_number'}
         if opts.get('all'):
             iter = difflinestates(pstates, states)
         else:
             iter = [('', l) for l in states]
         for change, l in iter:
             fm.startitem()
-            fm.data(node=fm.hexfunc(ctx.node()))
+            fm.data(node=fm.hexfunc(scmutil.binnode(ctx)))
+            showrev = not (opts.get('all') or opts.get('rev'))
             cols = [
                 ('filename', fn, True),
-                ('rev', rev, True),
+                ('rev', rev, showrev),
                 ('linenumber', l.linenum, opts.get('line_number')),
             ]
             if opts.get('all'):
@@ -2568,26 +2572,46 @@ 
 
     ui.pager('grep')
     fm = ui.formatter('grep', opts)
-    for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
-        rev = ctx.rev()
-        parent = ctx.p1().rev()
-        for fn in sorted(revfiles.get(rev, [])):
-            states = matches[rev][fn]
-            copy = copies.get(rev, {}).get(fn)
-            if fn in skip:
-                if copy:
-                    skip[copy] = True
+    # This if part handles the default situation,\
+    # when nothing is passed in -r or --all
+    if not (opts.get('rev')  or opts.get('all')):
+        rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
+        m = scmutil.match(repo[rev], pats, opts, default='relglob')
+        m.bad = lambda x, y: False
+        ctx = repo[rev]
+        ds = ctx.repo().dirstate
+
+        for fn in ctx.matches(m):
+            if rev is None and ds[fn] == 'r':
                 continue
-            pstates = matches.get(parent, {}).get(copy or fn, [])
-            if pstates or states:
-                r = display(fm, fn, ctx, pstates, states)
+            data = ctx.filectx(fn).data()
+            states = []
+            for lnum, cstart, cend, line in matchlines(data):
+                states.append(linestate(line, lnum, cstart, cend))
+            if states:
+                r = display(fm, fn, ctx, [], states)
                 found = found or r
-                if r and not opts.get('all'):
-                    skip[fn] = True
+    else :
+        for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
+            rev = ctx.rev()
+            parent = ctx.p1().rev()
+            for fn in sorted(revfiles.get(rev, [])):
+                states = matches[rev][fn]
+                copy = copies.get(rev, {}).get(fn)
+                if fn in skip:
                     if copy:
                         skip[copy] = True
-        del matches[rev]
-        del revfiles[rev]
+                    continue
+                pstates = matches.get(parent, {}).get(copy or fn, [])
+                if pstates or states:
+                    r = display(fm, fn, ctx, pstates, states)
+                    found = found or r
+                    if r and not opts.get('all'):
+                        skip[fn] = True
+                        if copy:
+                            skip[copy] = True
+            del matches[rev]
+            del revfiles[rev]
     fm.end()
 
     return not found